Skip to content

Commit 9acc9f4

Browse files
feat: add partitions progress bar to table info (#3206)
1 parent 2a6c613 commit 9acc9f4

File tree

13 files changed

+671
-44
lines changed

13 files changed

+671
-44
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
.ydb-partitions-progress {
2+
&__segment {
3+
display: flex;
4+
flex-basis: 0;
5+
6+
&_additional {
7+
min-width: 20px;
8+
}
9+
10+
&_main {
11+
min-width: 70px;
12+
}
13+
}
14+
15+
&__segment-bar {
16+
--segment-filled-bg-color: var(--g-color-base-neutral-heavy);
17+
--segment-empty-bg-color: var(--g-color-base-neutral-light);
18+
overflow: hidden;
19+
20+
height: 10px;
21+
22+
border-radius: var(--g-border-radius-xs);
23+
background-color: var(--segment-empty-bg-color);
24+
25+
&_additional {
26+
--segment-filled-bg-color: var(--g-color-base-danger-heavy);
27+
--segment-empty-bg-color: var(--g-color-base-danger-light);
28+
}
29+
30+
&_main {
31+
--segment-filled-bg-color: var(--g-color-base-info-heavy);
32+
--segment-empty-bg-color: var(--g-color-base-info-light);
33+
}
34+
}
35+
36+
&__segment-fill {
37+
height: 100%;
38+
39+
background-color: var(--segment-filled-bg-color);
40+
41+
transition:
42+
transform 0.6s ease,
43+
width 0.6s ease,
44+
background-color 0.6s ease;
45+
46+
&_min-fill {
47+
min-width: 20px;
48+
}
49+
}
50+
51+
&__segment-touched {
52+
padding: var(--g-spacing-2);
53+
54+
font-size: var(--g-text-body-2-font-size);
55+
line-height: var(--g-text-body-2-line-height);
56+
}
57+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import {Flex, Popover, Text} from '@gravity-ui/uikit';
2+
import {isNil} from 'lodash';
3+
4+
import {cn} from '../../../../../../utils/cn';
5+
6+
import {getPartitionsTooltip} from './helpers';
7+
import i18n from './i18n';
8+
import {FULL_FILL_VALUE, calcPartitionsProgress} from './utils';
9+
10+
import './PartitionsProgress.scss';
11+
12+
const b = cn('ydb-partitions-progress');
13+
14+
interface PartitionsProgressProps {
15+
minPartitions: number;
16+
maxPartitions?: number;
17+
partitionsCount: number;
18+
className?: string;
19+
}
20+
21+
type SegmentPosition = 'main' | 'additional';
22+
23+
const SEGMENT_MODS: Record<SegmentPosition, Record<string, boolean>> = {
24+
additional: {additional: true},
25+
main: {main: true},
26+
};
27+
28+
interface SegmentProgressBarProps {
29+
position: SegmentPosition;
30+
value: number;
31+
withMinFill?: boolean;
32+
}
33+
34+
const SegmentProgressBar = ({position, value, withMinFill}: SegmentProgressBarProps) => {
35+
const width = `${value}%`;
36+
37+
return (
38+
<div
39+
className={b('segment-bar', SEGMENT_MODS[position])}
40+
role="progressbar"
41+
aria-valuemin={0}
42+
aria-valuemax={FULL_FILL_VALUE}
43+
aria-valuenow={value}
44+
>
45+
<div className={b('segment-fill', {'min-fill': withMinFill})} style={{width}} />
46+
</div>
47+
);
48+
};
49+
50+
export const PartitionsProgress = ({
51+
minPartitions,
52+
maxPartitions,
53+
partitionsCount,
54+
className,
55+
}: PartitionsProgressProps) => {
56+
const {
57+
min,
58+
max,
59+
partitionsBelowMin,
60+
partitionsAboveMax,
61+
isBelowMin,
62+
isAboveMax,
63+
leftSegmentUnits,
64+
mainSegmentUnits,
65+
rightSegmentUnits,
66+
mainProgressValue,
67+
} = calcPartitionsProgress(minPartitions, maxPartitions, partitionsCount);
68+
69+
const tooltip = getPartitionsTooltip({
70+
count: partitionsCount,
71+
belowMin: partitionsBelowMin,
72+
aboveMax: partitionsAboveMax,
73+
isBelowMin: isBelowMin,
74+
isAboveMax: isAboveMax,
75+
});
76+
77+
const maxLabel = isNil(max) ? i18n('value_no-limit') : max;
78+
79+
const hasAdditionalSegments = isBelowMin || isAboveMax;
80+
const withMinFill = !hasAdditionalSegments;
81+
82+
return (
83+
<Popover hasArrow placement="top" content={tooltip} className={b('segment-touched')}>
84+
<Flex alignItems="center" gap="0.5" className={b(null, className)}>
85+
{isBelowMin && (
86+
<Flex
87+
style={{flexGrow: leftSegmentUnits}}
88+
direction="column"
89+
gap="2"
90+
className={b('segment', SEGMENT_MODS.additional)}
91+
>
92+
<SegmentProgressBar position="additional" value={FULL_FILL_VALUE} />
93+
94+
<Flex justifyContent="flex-start">
95+
<Text variant="body-2" color="secondary">
96+
{partitionsCount}
97+
</Text>
98+
</Flex>
99+
</Flex>
100+
)}
101+
102+
<Flex
103+
direction="column"
104+
className={b('segment', SEGMENT_MODS.main)}
105+
style={{flexGrow: mainSegmentUnits}}
106+
gap="2"
107+
>
108+
<SegmentProgressBar
109+
position="main"
110+
value={mainProgressValue}
111+
withMinFill={withMinFill}
112+
/>
113+
114+
<Flex justifyContent="space-between">
115+
<Text variant="body-2" color="secondary">
116+
{min}
117+
</Text>
118+
<Text variant="body-2" color="secondary">
119+
{maxLabel}
120+
</Text>
121+
</Flex>
122+
</Flex>
123+
124+
{isAboveMax && (
125+
<Flex
126+
direction="column"
127+
gap="2"
128+
className={b('segment', SEGMENT_MODS.additional)}
129+
style={{flexGrow: rightSegmentUnits}}
130+
>
131+
<SegmentProgressBar position="additional" value={FULL_FILL_VALUE} />
132+
133+
<Flex justifyContent="flex-end">
134+
<Text variant="body-2" color="secondary">
135+
{partitionsCount}
136+
</Text>
137+
</Flex>
138+
</Flex>
139+
)}
140+
</Flex>
141+
</Popover>
142+
);
143+
};

0 commit comments

Comments
 (0)