Skip to content

Commit 081fa1b

Browse files
committed
feat: redesign Memory section
1 parent 4222c14 commit 081fa1b

24 files changed

+733
-98
lines changed

src/components/MemoryViewer/MemoryViewer.scss

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
$memory-type-colors: (
2-
'AllocatorCachesMemory': var(--g-color-base-utility-medium-hover),
3-
'SharedCacheConsumption': var(--g-color-base-info-medium-hover),
4-
'MemTableConsumption': var(--g-color-base-warning-medium-hover),
5-
'QueryExecutionConsumption': var(--g-color-base-positive-medium-hover),
6-
'Other': var(--g-color-base-generic-medium-hover),
2+
'SharedCacheConsumption': var(--g-color-base-info-medium),
3+
'QueryExecutionConsumption': var(--g-color-base-positive-medium),
4+
'MemTableConsumption': var(--g-color-base-warning-medium),
5+
'AllocatorCachesMemory': var(--g-color-base-danger-medium),
6+
'Other': var(--g-color-base-neutral-medium),
77
);
88

99
@mixin memory-type-color($type) {

src/components/MemoryViewer/i18n/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"text_usage": "Usage",
88
"text_soft-limit": "Soft Limit",
99
"text_hard-limit": "Hard Limit",
10-
"text_other": "Other"
10+
"text_other": "Other",
11+
"text_memory-details": "Memory Details"
1112
}

src/components/MemoryViewer/utils.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,27 @@ export function getMaybeNumber(value: string | number | undefined): number | und
1313
return isNumeric(value) ? parseFloat(String(value)) : undefined;
1414
}
1515

16-
interface MemorySegment {
16+
export interface MemorySegment {
1717
label: string;
1818
key: string;
1919
value: number;
2020
capacity?: number;
2121
isInfo?: boolean;
2222
}
2323

24+
// Memory segment colors using CSS variables for theme support
25+
export const MEMORY_SEGMENT_COLORS: Record<string, string> = {
26+
SharedCacheConsumption: 'var(--g-color-base-info-medium)',
27+
QueryExecutionConsumption: 'var(--g-color-base-positive-medium)',
28+
MemTableConsumption: 'var(--g-color-base-warning-medium)',
29+
AllocatorCachesMemory: 'var(--g-color-base-danger-medium)',
30+
Other: 'var(--g-color-base-neutral-medium)',
31+
};
32+
33+
export function getMemorySegmentColor(key: string): string {
34+
return MEMORY_SEGMENT_COLORS[key] || MEMORY_SEGMENT_COLORS['Other'];
35+
}
36+
2437
export function getMemorySegments(stats: TMemoryStats, memoryUsage: number): MemorySegment[] {
2538
const segments = [
2639
{
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Flex, Text} from '@gravity-ui/uikit';
2+
3+
import {getProgressStyle} from './progressUtils';
4+
import type {ProgressContainerProps} from './types';
5+
6+
export function ProgressContainer({
7+
children,
8+
displayText,
9+
withValue = false,
10+
className,
11+
width,
12+
}: ProgressContainerProps) {
13+
const progressStyle = getProgressStyle(width);
14+
15+
return (
16+
<Flex alignItems="center" gap="2" className={className}>
17+
<div style={progressStyle}>{children}</div>
18+
{withValue && displayText && (
19+
<Text variant="body-1" color="secondary">
20+
{displayText}
21+
</Text>
22+
)}
23+
</Flex>
24+
);
25+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {SingleProgress} from './SingleProgress';
2+
import {StackProgress} from './StackProgress';
3+
import type {ProgressWrapperProps} from './types';
4+
5+
export function ProgressWrapper(props: ProgressWrapperProps) {
6+
if ('stack' in props && props.stack) {
7+
return <StackProgress {...props} />;
8+
}
9+
return <SingleProgress {...props} />;
10+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react';
2+
3+
import {Progress} from '@gravity-ui/uikit';
4+
5+
import {defaultFormatProgressValues} from '../../utils/progress';
6+
import {safeParseNumber} from '../../utils/utils';
7+
8+
import {ProgressContainer} from './ProgressContainer';
9+
import i18n from './i18n';
10+
import {
11+
PROGRESS_SIZE,
12+
calculateProgressWidth,
13+
formatDisplayValues,
14+
formatProgressText,
15+
isValidValue,
16+
} from './progressUtils';
17+
import type {ProgressWrapperSingleProps} from './types';
18+
19+
export function SingleProgress({
20+
value,
21+
capacity,
22+
formatValues = defaultFormatProgressValues,
23+
className,
24+
width,
25+
size = PROGRESS_SIZE,
26+
withValue = false,
27+
}: ProgressWrapperSingleProps) {
28+
if (!isValidValue(value)) {
29+
return <div className={className}>{i18n('alert_no-data')}</div>;
30+
}
31+
32+
const numericValue = safeParseNumber(value);
33+
const numericCapacity = safeParseNumber(capacity);
34+
const clampedFillWidth = calculateProgressWidth(numericValue, numericCapacity);
35+
36+
const [valueText, capacityText] = React.useMemo(() => {
37+
return formatDisplayValues(value, capacity, formatValues);
38+
}, [formatValues, value, capacity]);
39+
40+
const displayText = React.useMemo(() => {
41+
return formatProgressText(valueText, capacityText, numericCapacity);
42+
}, [valueText, capacityText, numericCapacity]);
43+
44+
return (
45+
<ProgressContainer
46+
displayText={displayText}
47+
withValue={withValue}
48+
className={className}
49+
width={width}
50+
>
51+
<Progress value={clampedFillWidth} theme="success" size={size} />
52+
</ProgressContainer>
53+
);
54+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React from 'react';
2+
3+
import {Progress} from '@gravity-ui/uikit';
4+
5+
import {defaultFormatProgressValues} from '../../utils/progress';
6+
import {safeParseNumber} from '../../utils/utils';
7+
import {getMemorySegmentColor} from '../MemoryViewer/utils';
8+
9+
import {ProgressContainer} from './ProgressContainer';
10+
import i18n from './i18n';
11+
import {
12+
MAX_PERCENTAGE,
13+
PROGRESS_SIZE,
14+
formatDisplayValues,
15+
formatProgressText,
16+
} from './progressUtils';
17+
import type {ProgressWrapperStackProps} from './types';
18+
19+
export function StackProgress({
20+
stack,
21+
totalCapacity,
22+
formatValues = defaultFormatProgressValues,
23+
className,
24+
width,
25+
size = PROGRESS_SIZE,
26+
withValue = false,
27+
}: ProgressWrapperStackProps) {
28+
const displaySegments = React.useMemo(() => {
29+
return stack.filter((segment) => !segment.isInfo && segment.value > 0);
30+
}, [stack]);
31+
32+
if (displaySegments.length === 0) {
33+
return <div className={className}>{i18n('alert_no-data')}</div>;
34+
}
35+
36+
const totalValue = React.useMemo(() => {
37+
return displaySegments.reduce((sum, segment) => sum + segment.value, 0);
38+
}, [displaySegments]);
39+
40+
const numericTotalCapacity = React.useMemo(() => {
41+
return safeParseNumber(totalCapacity);
42+
}, [totalCapacity]);
43+
44+
const maxValue = numericTotalCapacity || totalValue;
45+
46+
const stackElements = React.useMemo(() => {
47+
return displaySegments.map((segment) => ({
48+
value: maxValue > 0 ? (segment.value / maxValue) * MAX_PERCENTAGE : 0,
49+
color: getMemorySegmentColor(segment.key),
50+
title: segment.label,
51+
}));
52+
}, [displaySegments, maxValue]);
53+
54+
const [totalValueText, totalCapacityText] = React.useMemo(() => {
55+
return formatDisplayValues(totalValue, numericTotalCapacity || totalValue, formatValues);
56+
}, [formatValues, totalValue, numericTotalCapacity]);
57+
58+
const displayText = React.useMemo(() => {
59+
return formatProgressText(totalValueText, totalCapacityText, numericTotalCapacity || 0);
60+
}, [totalValueText, totalCapacityText, numericTotalCapacity]);
61+
62+
return (
63+
<ProgressContainer
64+
displayText={displayText}
65+
withValue={withValue}
66+
className={className}
67+
width={width}
68+
>
69+
<Progress value={MAX_PERCENTAGE} stack={stackElements} size={size} />
70+
</ProgressContainer>
71+
);
72+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"alert_no-data": "no data",
3+
"context_capacity-usage": "{{value}} of {{capacity}}"
4+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {registerKeysets} from '../../../utils/i18n';
2+
3+
import en from './en.json';
4+
5+
const COMPONENT = 'progress-wrapper';
6+
7+
const keysets = {
8+
en,
9+
};
10+
11+
export default registerKeysets(COMPONENT, keysets);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Main component - public API
2+
export {ProgressWrapper} from './ProgressWrapper';
3+
4+
// Individual components - for direct usage if needed
5+
export {SingleProgress} from './SingleProgress';
6+
export {StackProgress} from './StackProgress';
7+
export {ProgressContainer} from './ProgressContainer';
8+
9+
// Types - for consumers
10+
export type {
11+
ProgressWrapperProps,
12+
ProgressWrapperSingleProps,
13+
ProgressWrapperStackProps,
14+
ProgressContainerProps,
15+
} from './types';
16+
17+
// Utils - for advanced usage
18+
export * from './progressUtils';

0 commit comments

Comments
 (0)