11import { useState } from 'react' ;
22import cn from 'bem-cn-lite' ;
3- import _ from 'lodash' ;
3+ import { isEmpty } from 'lodash/fp ' ;
44
55import { ArrowToggle , Button , Popover } from '@gravity-ui/uikit' ;
66
7- import DataTable , { Column , Settings } from '@gravity-ui/react-data-table' ;
8-
9- import EntityStatus from '../../../components/EntityStatus/EntityStatus' ;
10- import InfoViewer from '../../../components/InfoViewer/InfoViewer' ;
11- import { ProgressViewer } from '../../../components/ProgressViewer/ProgressViewer' ;
12- import { Icon } from '../../../components/Icon' ;
13- import { Vdisk } from './Vdisk' ;
7+ import DataTable , { type Column } from '@gravity-ui/react-data-table' ;
148
9+ import type { ValueOf } from '../../../types/common' ;
10+ import type {
11+ PreparedStructurePDisk ,
12+ PreparedStructureVDisk ,
13+ } from '../../../store/reducers/node/types' ;
14+ import { EVDiskState } from '../../../types/api/vdisk' ;
1515import { bytesToGB , pad9 } from '../../../utils/utils' ;
1616import { formatStorageValuesToGb } from '../../../utils/dataFormatters/dataFormatters' ;
1717import { getPDiskType } from '../../../utils/pdisk' ;
18-
1918import { DEFAULT_TABLE_SETTINGS } from '../../../utils/constants' ;
19+ import EntityStatus from '../../../components/EntityStatus/EntityStatus' ;
20+ import InfoViewer , { type InfoViewerItem } from '../../../components/InfoViewer/InfoViewer' ;
21+ import { ProgressViewer } from '../../../components/ProgressViewer/ProgressViewer' ;
22+ import { Icon } from '../../../components/Icon' ;
23+
24+ import { Vdisk } from './Vdisk' ;
2025import { valueIsDefined } from './NodeStructure' ;
2126import { PDiskTitleBadge } from './PDiskTitleBadge' ;
2227
2328const b = cn ( 'kv-node-structure' ) ;
2429
2530interface PDiskProps {
26- data : Record < string , any > ;
31+ data : PreparedStructurePDisk ;
2732 unfolded ?: boolean ;
2833 id : string ;
2934 selectedVdiskId ?: string ;
@@ -37,8 +42,7 @@ enum VDiskTableColumnsIds {
3742 Info = 'Info' ,
3843}
3944
40- type VDiskTableColumnsIdsKeys = keyof typeof VDiskTableColumnsIds ;
41- type VDiskTableColumnsIdsValues = typeof VDiskTableColumnsIds [ VDiskTableColumnsIdsKeys ] ;
45+ type VDiskTableColumnsIdsValues = ValueOf < typeof VDiskTableColumnsIds > ;
4246
4347const vDiskTableColumnsNames : Record < VDiskTableColumnsIdsValues , string > = {
4448 VDiskSlotId : 'Slot id' ,
@@ -47,39 +51,35 @@ const vDiskTableColumnsNames: Record<VDiskTableColumnsIdsValues, string> = {
4751 Info : '' ,
4852} ;
4953
50- interface RowType {
51- id : string ;
52- [ VDiskTableColumnsIds . slotId ] : number ;
53- [ VDiskTableColumnsIds . VDiskState ] : string ;
54- AllocatedSize : string ;
55- AvailableSize : string ;
56- }
57-
5854function getColumns ( {
5955 pDiskId,
6056 selectedVdiskId,
6157 nodeHref,
6258} : {
63- pDiskId : number ;
59+ pDiskId : number | undefined ;
6460 selectedVdiskId ?: string ;
6561 nodeHref ?: string | null ;
6662} ) {
67- const columns : Column < RowType > [ ] = [
63+ const columns : Column < PreparedStructureVDisk > [ ] = [
6864 {
69- name : VDiskTableColumnsIds . slotId as string ,
65+ name : VDiskTableColumnsIds . slotId ,
7066 header : vDiskTableColumnsNames [ VDiskTableColumnsIds . slotId ] ,
7167 width : 100 ,
72- render : ( { value , row} ) => {
68+ render : ( { row} ) => {
7369 let vdiskInternalViewerLink = '' ;
7470
75- if ( nodeHref && value !== undefined ) {
71+ if ( nodeHref && pDiskId !== undefined && row . VDiskSlotId !== undefined ) {
7672 vdiskInternalViewerLink +=
77- nodeHref + 'actors/vdisks/vdisk' + pad9 ( pDiskId ) + '_' + pad9 ( value ) ;
73+ nodeHref +
74+ 'actors/vdisks/vdisk' +
75+ pad9 ( pDiskId ) +
76+ '_' +
77+ pad9 ( row . VDiskSlotId ) ;
7878 }
7979
8080 return (
8181 < div className = { b ( 'vdisk-id' , { selected : row . id === selectedVdiskId } ) } >
82- < span > { value as number } </ span >
82+ < span > { row . VDiskSlotId } </ span >
8383 { vdiskInternalViewerLink && (
8484 < Button
8585 size = "s"
@@ -96,17 +96,19 @@ function getColumns({
9696 align : DataTable . LEFT ,
9797 } ,
9898 {
99- name : VDiskTableColumnsIds . VDiskState as string ,
99+ name : VDiskTableColumnsIds . VDiskState ,
100100 header : vDiskTableColumnsNames [ VDiskTableColumnsIds . VDiskState ] ,
101101 width : 70 ,
102- render : ( { value} ) => {
103- return < EntityStatus status = { value === 'OK' ? 'green' : 'red' } /> ;
102+ render : ( { row} ) => {
103+ return (
104+ < EntityStatus status = { row . VDiskState === EVDiskState . OK ? 'green' : 'red' } />
105+ ) ;
104106 } ,
105- sortAccessor : ( row ) => ( row [ VDiskTableColumnsIds . VDiskState ] === 'OK' ? 1 : 0 ) ,
107+ sortAccessor : ( row ) => ( row . VDiskState === EVDiskState . OK ? 1 : 0 ) ,
106108 align : DataTable . CENTER ,
107109 } ,
108110 {
109- name : VDiskTableColumnsIds . Size as string ,
111+ name : VDiskTableColumnsIds . Size ,
110112 header : vDiskTableColumnsNames [ VDiskTableColumnsIds . Size ] ,
111113 width : 100 ,
112114 render : ( { row} ) => {
@@ -123,7 +125,7 @@ function getColumns({
123125 align : DataTable . CENTER ,
124126 } ,
125127 {
126- name : VDiskTableColumnsIds . Info as string ,
128+ name : VDiskTableColumnsIds . Info ,
127129 header : vDiskTableColumnsNames [ VDiskTableColumnsIds . Info ] ,
128130 width : 70 ,
129131 render : ( { row} ) => {
@@ -150,10 +152,31 @@ function getColumns({
150152 return columns ;
151153}
152154
153- export function PDisk ( props : PDiskProps ) {
154- const [ unfolded , setUnfolded ] = useState ( props . unfolded ?? false ) ;
155+ export function PDisk ( {
156+ id,
157+ data,
158+ selectedVdiskId,
159+ nodeHref,
160+ unfolded : unfoldedFromProps ,
161+ } : PDiskProps ) {
162+ const [ unfolded , setUnfolded ] = useState ( unfoldedFromProps ?? false ) ;
163+
164+ const {
165+ TotalSize = 0 ,
166+ AvailableSize = 0 ,
167+ Device,
168+ Guid,
169+ PDiskId,
170+ Path,
171+ Realtime,
172+ State,
173+ Category,
174+ SerialNumber,
175+ vDisks,
176+ } = data ;
155177
156- const data = props . data ?? { } ;
178+ const total = Number ( TotalSize ) ;
179+ const available = Number ( AvailableSize ) ;
157180
158181 const onOpenPDiskDetails = ( ) => {
159182 setUnfolded ( true ) ;
@@ -163,15 +186,12 @@ export function PDisk(props: PDiskProps) {
163186 } ;
164187
165188 const renderVDisks = ( ) => {
166- const { selectedVdiskId, data, nodeHref} = props ;
167- const { vDisks} = data ;
168-
169189 return (
170190 < DataTable
171191 theme = "yandex-cloud"
172192 data = { vDisks }
173- columns = { getColumns ( { nodeHref, pDiskId : data . PDiskId , selectedVdiskId} ) }
174- settings = { { ...DEFAULT_TABLE_SETTINGS , dynamicRender : false } as Settings }
193+ columns = { getColumns ( { nodeHref, pDiskId : PDiskId , selectedVdiskId} ) }
194+ settings = { { ...DEFAULT_TABLE_SETTINGS , dynamicRender : false } }
175195 rowClassName = { ( row ) => {
176196 return row . id === selectedVdiskId ? b ( 'selected-vdisk' ) : '' ;
177197 } }
@@ -180,30 +200,16 @@ export function PDisk(props: PDiskProps) {
180200 } ;
181201
182202 const renderPDiskDetails = ( ) => {
183- if ( _ . isEmpty ( data ) ) {
203+ if ( isEmpty ( data ) ) {
184204 return < div > No information about PDisk</ div > ;
185205 }
186- const { nodeHref} = props ;
187- const {
188- TotalSize,
189- AvailableSize,
190- Device,
191- Guid,
192- PDiskId,
193- Path,
194- Realtime,
195- State,
196- Category,
197- SerialNumber,
198- } = data ;
199-
200206 let pDiskInternalViewerLink = '' ;
201207
202208 if ( nodeHref ) {
203209 pDiskInternalViewerLink += nodeHref + 'actors/pdisks/pdisk' + pad9 ( PDiskId ) ;
204210 }
205211
206- const pdiskInfo : any = [
212+ const pdiskInfo : InfoViewerItem [ ] = [
207213 {
208214 label : 'PDisk Id' ,
209215 value : (
@@ -236,19 +242,19 @@ export function PDisk(props: PDiskProps) {
236242 }
237243 pdiskInfo . push ( {
238244 label : 'Allocated Size' ,
239- value : bytesToGB ( TotalSize - AvailableSize ) ,
245+ value : bytesToGB ( total - available ) ,
240246 } ) ;
241247 pdiskInfo . push ( {
242248 label : 'Available Size' ,
243- value : bytesToGB ( AvailableSize ) ,
249+ value : bytesToGB ( available ) ,
244250 } ) ;
245- if ( Number ( TotalSize ) >= 0 && Number ( AvailableSize ) >= 0 ) {
251+ if ( total >= 0 && available >= 0 ) {
246252 pdiskInfo . push ( {
247253 label : 'Size' ,
248254 value : (
249255 < ProgressViewer
250- value = { TotalSize - AvailableSize }
251- capacity = { TotalSize }
256+ value = { total - available }
257+ capacity = { total }
252258 formatValues = { formatStorageValuesToGb }
253259 colorizeProgress = { true }
254260 className = { b ( 'size' ) }
@@ -286,24 +292,24 @@ export function PDisk(props: PDiskProps) {
286292 } ;
287293
288294 return (
289- < div className = { b ( 'pdisk' ) } id = { props . id } >
295+ < div className = { b ( 'pdisk' ) } id = { id } >
290296 < div className = { b ( 'pdisk-header' ) } >
291297 < div className = { b ( 'pdisk-title-wrapper' ) } >
292- < EntityStatus status = { data . Device } />
298+ < EntityStatus status = { Device } />
293299 < PDiskTitleBadge
294300 label = "PDiskID"
295- value = { data . PDiskId }
301+ value = { PDiskId }
296302 className = { b ( 'pdisk-title-id' ) }
297303 />
298304 < PDiskTitleBadge value = { getPDiskType ( data ) } className = { b ( 'pdisk-title-type' ) } />
299305 < ProgressViewer
300- value = { data . TotalSize - data . AvailableSize }
301- capacity = { data . TotalSize }
306+ value = { total - available }
307+ capacity = { total }
302308 formatValues = { formatStorageValuesToGb }
303309 colorizeProgress = { true }
304310 className = { b ( 'pdisk-title-size' ) }
305311 />
306- < PDiskTitleBadge label = "VDisks" value = { data . vDisks . length } />
312+ < PDiskTitleBadge label = "VDisks" value = { vDisks . length } />
307313 </ div >
308314 < Button
309315 onClick = { unfolded ? onClosePDiskDetails : onOpenPDiskDetails }
0 commit comments