-
Notifications
You must be signed in to change notification settings - Fork 21
fix(PDiskSpaceDistribution): slot height calculation #3897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,5 @@ | ||||||||||||||||||||||||||||
| import React from 'react'; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import {DiskStateProgressBar} from '../../../components/DiskStateProgressBar/DiskStateProgressBar'; | ||||||||||||||||||||||||||||
| import {HoverPopup} from '../../../components/HoverPopup/HoverPopup'; | ||||||||||||||||||||||||||||
| import {InternalLink} from '../../../components/InternalLink'; | ||||||||||||||||||||||||||||
|
|
@@ -26,7 +28,7 @@ import './PDiskSpaceDistribution.scss'; | |||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const b = cn('ydb-pdisk-space-distribution'); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const SLOT_HEIGHT = 40; | ||||||||||||||||||||||||||||
| const BASE_SLOT_HEIGHT = 40; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| interface PDiskSpaceDistributionProps { | ||||||||||||||||||||||||||||
| data: PDiskData; | ||||||||||||||||||||||||||||
|
|
@@ -38,13 +40,33 @@ export function PDiskSpaceDistribution({data}: PDiskSpaceDistributionProps) { | |||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const {PDiskId, NodeId} = data; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const containerHeight = SLOT_HEIGHT * (SlotItems?.length || 1); | ||||||||||||||||||||||||||||
| // Find the minimum Total among non-log slots to use as the base unit for height scaling | ||||||||||||||||||||||||||||
| const minNonLogTotal = React.useMemo(() => { | ||||||||||||||||||||||||||||
| if (!SlotItems?.length) { | ||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let minTotal = Infinity; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for (const item of SlotItems) { | ||||||||||||||||||||||||||||
| if (item.SlotType === 'log') { | ||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| const value = Number(item.Total) || 1; | ||||||||||||||||||||||||||||
| if (value < minTotal) { | ||||||||||||||||||||||||||||
| minTotal = value; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return minTotal === Infinity ? 1 : minTotal; | ||||||||||||||||||||||||||||
| }, [SlotItems]); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const renderSlots = () => { | ||||||||||||||||||||||||||||
| return SlotItems?.map((item, index) => { | ||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||
| <Slot | ||||||||||||||||||||||||||||
| item={item} | ||||||||||||||||||||||||||||
| minNonLogTotal={minNonLogTotal} | ||||||||||||||||||||||||||||
| pDiskId={PDiskId} | ||||||||||||||||||||||||||||
| nodeId={NodeId} | ||||||||||||||||||||||||||||
| getVDiskPagePath={getVDiskPagePath} | ||||||||||||||||||||||||||||
|
|
@@ -59,13 +81,7 @@ export function PDiskSpaceDistribution({data}: PDiskSpaceDistributionProps) { | |||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||
| className={b(null)} | ||||||||||||||||||||||||||||
| style={{ | ||||||||||||||||||||||||||||
| height: containerHeight, | ||||||||||||||||||||||||||||
| minHeight: containerHeight, | ||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||
| <div className={b(null)}> | ||||||||||||||||||||||||||||
| <DiskStateProgressBar | ||||||||||||||||||||||||||||
| className={b('pdisk-bar')} | ||||||||||||||||||||||||||||
| severity={data.Severity} | ||||||||||||||||||||||||||||
|
|
@@ -80,6 +96,7 @@ export function PDiskSpaceDistribution({data}: PDiskSpaceDistributionProps) { | |||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| interface SlotProps<T extends SlotItemType> { | ||||||||||||||||||||||||||||
| item: SlotItem<T>; | ||||||||||||||||||||||||||||
| minNonLogTotal: number; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| pDiskId?: string | number; | ||||||||||||||||||||||||||||
| nodeId?: string | number; | ||||||||||||||||||||||||||||
|
|
@@ -89,7 +106,12 @@ interface SlotProps<T extends SlotItemType> { | |||||||||||||||||||||||||||
| ) => string | undefined; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| function Slot<T extends SlotItemType>({item, nodeId, getVDiskPagePath}: SlotProps<T>) { | ||||||||||||||||||||||||||||
| function Slot<T extends SlotItemType>({ | ||||||||||||||||||||||||||||
| item, | ||||||||||||||||||||||||||||
| minNonLogTotal, | ||||||||||||||||||||||||||||
| nodeId, | ||||||||||||||||||||||||||||
| getVDiskPagePath, | ||||||||||||||||||||||||||||
| }: SlotProps<T>) { | ||||||||||||||||||||||||||||
| const renderContent = () => { | ||||||||||||||||||||||||||||
| if (isVDiskSlot(item)) { | ||||||||||||||||||||||||||||
| const vDiskPagePath = getVDiskPagePath?.({ | ||||||||||||||||||||||||||||
|
|
@@ -175,8 +197,14 @@ function Slot<T extends SlotItemType>({item, nodeId, getVDiskPagePath}: SlotProp | |||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Log slots get half the base height; others scale proportionally to the smallest non-log slot | ||||||||||||||||||||||||||||
| const slotHeight = | ||||||||||||||||||||||||||||
| item.SlotType === 'log' | ||||||||||||||||||||||||||||
| ? BASE_SLOT_HEIGHT / 2 | ||||||||||||||||||||||||||||
| : ((Number(item.Total) || 1) / minNonLogTotal) * BASE_SLOT_HEIGHT; | ||||||||||||||||||||||||||||
|
Comment on lines
+200
to
+204
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.tsx
Line: 200-204
Comment:
When `item.Total` is `undefined`, `null`, or `0` for any non-log slot, `Number(item.Total) || 1` normalises it to `1`. That `1` then wins the `minNonLogTotal` search, so every other slot with a real capacity — say 100 GB = `107_374_182_400` — computes a height of `(107_374_182_400 / 1) × 40 ≈ 4.3 × 10¹²px`, effectively freezing the page. Adding a `Math.min` cap (e.g. `10 × BASE_SLOT_HEIGHT`) keeps the layout sensible even when data is incomplete.
```suggestion
// Log slots get half the base height; others scale proportionally to the smallest non-log slot
const slotHeight =
item.SlotType === 'log'
? BASE_SLOT_HEIGHT / 2
: Math.min(
((Number(item.Total) || 1) / minNonLogTotal) * BASE_SLOT_HEIGHT,
10 * BASE_SLOT_HEIGHT,
);
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||
| <div className={b('slot-wrapper')} style={{flexGrow: Number(item.Total) || 1}}> | ||||||||||||||||||||||||||||
| <div className={b('slot-wrapper')} style={{height: slotHeight}}> | ||||||||||||||||||||||||||||
| {renderContent()} | ||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When any non-log slot has a missing, zero, or
NaNTotal, this fallback makesminNonLogTotalequal to1. The new height calculation then divides real byte-sized slots by that value, so a normal 20 GB empty slot renders as about 800,000,000,000 px tall. This can happen with partial/older VDisk data whereSizeLimitis unavailable whileExpectedSlotCountstill creates empty slots; the previous flex layout kept the total bar height bounded, but these fixed pixel heights can make the PDisk page unusable.Useful? React with 👍 / 👎.