Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/components/CellWithPopover/CellWithPopover.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@
.g-popover__handler {
display: inline;
}

&_full-width {
width: 100%;
}
}
}
6 changes: 4 additions & 2 deletions src/components/CellWithPopover/CellWithPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const b = cn('ydb-cell-with-popover');

interface CellWithPopoverProps extends PopoverProps {
wrapperClassName?: string;
fullWidth?: boolean;
}

const DELAY_TIMEOUT = 100;
Expand All @@ -17,14 +18,15 @@ export function CellWithPopover({
children,
className,
wrapperClassName,
fullWidth,
...props
}: CellWithPopoverProps) {
return (
<div className={b(null, wrapperClassName)}>
<div className={b({fullWidth}, wrapperClassName)}>
<Popover
delayClosing={DELAY_TIMEOUT}
delayOpening={DELAY_TIMEOUT}
className={b('popover', className)}
className={b('popover', {'full-width': fullWidth}, className)}
{...props}
>
{children}
Expand Down
11 changes: 11 additions & 0 deletions src/components/ProgressViewer/ProgressViewer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
border-radius: 2px;
background: var(--g-color-base-generic);

&_vertical {
min-width: unset;
}

&_theme_dark {
color: var(--g-color-text-light-primary);

Expand Down Expand Up @@ -58,6 +62,13 @@
left: 0;

height: 100%;

&_vertical {
top: auto;
bottom: 0;

width: 100%;
}
}

&__text {
Expand Down
20 changes: 14 additions & 6 deletions src/components/ProgressViewer/ProgressViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export interface ProgressViewerProps {
inverseColorize?: boolean;
warningThreshold?: number;
dangerThreshold?: number;
vertical?: boolean;
hideCapacity?: boolean;
}

export function ProgressViewer({
Expand All @@ -56,11 +58,13 @@ export function ProgressViewer({
formatValues = defaultFormatValues,
percents,
className,
vertical,
size = 'xs',
colorizeProgress,
inverseColorize,
warningThreshold = 60,
dangerThreshold = 80,
hideCapacity,
}: ProgressViewerProps) {
const theme = useTheme();

Expand Down Expand Up @@ -89,12 +93,16 @@ export function ProgressViewer({
fillWidth = 100;
}

const lineStyle = {
width: fillWidth + '%',
};
const lineStyle = vertical
? {
height: fillWidth + '%',
}
: {
width: fillWidth + '%',
};

const renderContent = () => {
if (isNumeric(capacity)) {
if (isNumeric(capacity) && !hideCapacity) {
return `${valueText} ${divider} ${capacityText}`;
}

Expand All @@ -103,8 +111,8 @@ export function ProgressViewer({

if (isNumeric(value)) {
return (
<div className={b({size, theme, status}, className)}>
<div className={b('line')} style={lineStyle}></div>
<div className={b({size, theme, status, vertical}, className)}>
<div className={b('line', {vertical})} style={lineStyle}></div>
<span className={b('text')}>{renderContent()}</span>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {TPoolStats} from '../../../types/api/nodes';
import {InfoViewer, createInfoFormatter, formatObject} from '../../InfoViewer';

const formatPool = createInfoFormatter<TPoolStats>({
export const formatPool = createInfoFormatter<TPoolStats>({
values: {
Usage: (value) => value && `${(Number(value) * 100).toFixed(2)} %`,
},
Expand Down
104 changes: 103 additions & 1 deletion src/components/nodesColumns/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import DataTable from '@gravity-ui/react-data-table';
import {DefinitionList} from '@gravity-ui/uikit';

import {getLoadSeverityForNode} from '../../store/reducers/nodes/utils';
import type {TPoolStats} from '../../types/api/nodes';
import type {TTabletStateInfo} from '../../types/api/tablet';
import {valueIsDefined} from '../../utils';
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
import {formatStorageValuesToGb} from '../../utils/dataFormatters/dataFormatters';
import {
formatStorageValues,
formatStorageValuesToGb,
} from '../../utils/dataFormatters/dataFormatters';
import {getSpaceUsageSeverity} from '../../utils/storage';
import type {Column} from '../../utils/tableUtils/types';
import {isNumeric} from '../../utils/utils';
import {CellWithPopover} from '../CellWithPopover/CellWithPopover';
import {NodeHostWrapper} from '../NodeHostWrapper/NodeHostWrapper';
import type {NodeHostData} from '../NodeHostWrapper/NodeHostWrapper';
import {PoolsGraph} from '../PoolsGraph/PoolsGraph';
import {ProgressViewer} from '../ProgressViewer/ProgressViewer';
import {TabletsStatistic} from '../TabletsStatistic';
import {formatPool} from '../TooltipsContent';
import {UsageLabel} from '../UsageLabel/UsageLabel';

import {NODES_COLUMNS_IDS, NODES_COLUMNS_TITLES} from './constants';
import i18n from './i18n';
import type {GetNodesColumnsParams} from './types';

export function getNodeIdColumn<T extends {NodeId?: string | number}>(): Column<T> {
Expand Down Expand Up @@ -111,6 +118,57 @@ export function getMemoryColumn<
resizeMinWidth: 170,
};
}

export function getRAMColumn<T extends {MemoryUsed?: string; MemoryLimit?: string}>(): Column<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no sorting for new columns if table is paginated.

Currently, for every column name is checked with isSortableNodesProperty, if name is in the list, the column is sortable and it's name is sent to backend as sort param.

I'm not sure what's to do in this case, since there are two columns with different ids, but they have the same sort fields (CPU and Memory).

Probably, you can use not column name, but add separate sortField property to every column object (in such case it's better to do it in a separate PR, since it's a lot of refactoring). Maybe there is a better and easier solution

Copy link
Collaborator Author

@astandrik astandrik Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created dictionary for sort values

not sure if it's the best solution in the world, but as far as we decided to rename CPU to Pools looks like there are not so many choices left...

return {
name: NODES_COLUMNS_IDS.RAM,
header: NODES_COLUMNS_TITLES.RAM,
sortAccessor: ({MemoryUsed = 0}) => Number(MemoryUsed),
defaultOrder: DataTable.DESCENDING,
render: ({row}) => {
const [memoryUsed, memoryLimit] =
isNumeric(row.MemoryUsed) && isNumeric(row.MemoryLimit)
? formatStorageValues(
Number(row.MemoryUsed),
Number(row.MemoryLimit),
'gb',
undefined,
true,
)
: [0, 0];
return (
<CellWithPopover
placement={['top', 'auto']}
fullWidth
content={
<DefinitionList responsive>
<DefinitionList.Item name={i18n('field_memory-used')}>
{memoryUsed}
</DefinitionList.Item>
<DefinitionList.Item name={i18n('field_memory-limit')}>
{memoryLimit}
</DefinitionList.Item>
</DefinitionList>
}
>
<ProgressViewer
value={row.MemoryUsed}
capacity={row.MemoryLimit}
formatValues={(value, total) =>
formatStorageValues(value, total, 'gb', undefined, true)
}
colorizeProgress
vertical
hideCapacity
/>
</CellWithPopover>
);
},
align: DataTable.LEFT,
width: 85,
resizeMinWidth: 40,
};
}
export function getSharedCacheUsageColumn<
T extends {SharedCacheUsed?: string | number; SharedCacheLimit?: string | number},
>(): Column<T> {
Expand Down Expand Up @@ -143,6 +201,50 @@ export function getCpuColumn<T extends {PoolStats?: TPoolStats[]}>(): Column<T>
resizeMinWidth: 60,
};
}
export function getTotalCpuColumn<T extends {PoolStats?: TPoolStats[]}>(): Column<T> {
return {
name: NODES_COLUMNS_IDS.TotalCPU,
header: NODES_COLUMNS_TITLES.TotalCPU,
sortAccessor: ({PoolStats = []}) => Math.max(...PoolStats.map(({Usage}) => Number(Usage))),
defaultOrder: DataTable.DESCENDING,
render: ({row}) => {
if (!row.PoolStats) {
return EMPTY_DATA_PLACEHOLDER;
}

const totalPoolUsage = row.PoolStats.reduce((acc, pool) => acc + (pool.Usage || 0), 0);

return (
<CellWithPopover
placement={['top', 'auto']}
fullWidth
content={
<DefinitionList responsive>
{row.PoolStats.map((pool) =>
isNumeric(pool.Usage) ? (
<DefinitionList.Item key={pool.Name} name={pool.Name}>
{formatPool('Usage', pool.Usage).value}
</DefinitionList.Item>
) : null,
)}
</DefinitionList>
}
>
<ProgressViewer
value={totalPoolUsage}
capacity={1}
colorizeProgress
percents
vertical
/>
</CellWithPopover>
);
},
align: DataTable.LEFT,
width: 85,
resizeMinWidth: 40,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks strange when resized. Let's do either with fixed bar width or non-resizable column.
Screenshot 2024-10-31 at 18 16 58

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reworked

};
}
export function getLoadAverageColumn<T extends {LoadAveragePercents?: number[]}>(): Column<T> {
return {
name: NODES_COLUMNS_IDS.LoadAverage,
Expand Down
10 changes: 10 additions & 0 deletions src/components/nodesColumns/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export const NODES_COLUMNS_IDS = {
Version: 'Version',
Uptime: 'Uptime',
Memory: 'Memory',
RAM: 'RAM',
CPU: 'CPU',
TotalCPU: 'TotalCPU',
LoadAverage: 'LoadAverage',
Load: 'Load',
DiskSpaceUsage: 'DiskSpaceUsage',
Expand Down Expand Up @@ -54,9 +56,15 @@ export const NODES_COLUMNS_TITLES = {
get Memory() {
return i18n('memory');
},
get RAM() {
return i18n('ram');
},
get CPU() {
return i18n('cpu');
},
get TotalCPU() {
return i18n('totalcpu');
},
get LoadAverage() {
return i18n('load-average');
},
Expand Down Expand Up @@ -94,7 +102,9 @@ export const NODES_COLUMNS_TO_DATA_FIELDS: Record<NodesColumnId, NodesRequiredFi
Version: ['Version'],
Uptime: ['Uptime'],
Memory: ['Memory'],
RAM: ['Memory'],
CPU: ['CPU'],
TotalCPU: ['CPU'],
LoadAverage: ['LoadAverage'],
Load: ['LoadAverage'],
DiskSpaceUsage: ['DiskSpaceUsage'],
Expand Down
6 changes: 5 additions & 1 deletion src/components/nodesColumns/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
"version": "Version",
"uptime": "Uptime",
"memory": "Memory",
"ram": "RAM",
"cpu": "CPU",
"totalcpu": "TotalCPU",
"disk-usage": "Disk usage",
"tablets": "Tablets",
"load-average": "Load Average",
"load": "Load",
"caches": "Caches",
"sessions": "Sessions",
"missing": "Missing",
"pdisks": "PDisks"
"pdisks": "PDisks",
"field_memory-used": "Memory used",
"field_memory-limit": "Memory limit"
}
4 changes: 4 additions & 0 deletions src/containers/Nodes/columns/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
getMemoryColumn,
getNodeIdColumn,
getNodeNameColumn,
getRAMColumn,
getRackColumn,
getTabletsColumn,
getTotalCpuColumn,
getUptimeColumn,
getVersionColumn,
} from '../../../components/nodesColumns/columns';
Expand All @@ -26,7 +28,9 @@ export function getNodesColumns(params: GetNodesColumnsParams): Column<NodesPrep
getVersionColumn<NodesPreparedEntity>(),
getUptimeColumn<NodesPreparedEntity>(),
getMemoryColumn<NodesPreparedEntity>(),
getRAMColumn<NodesPreparedEntity>(),
getCpuColumn<NodesPreparedEntity>(),
getTotalCpuColumn<NodesPreparedEntity>(),
getLoadAverageColumn<NodesPreparedEntity>(),
getTabletsColumn<NodesPreparedEntity>(params),
];
Expand Down
Loading