From 50bad3d7cc47084c5c72c50fade806c028e52044 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Mon, 1 Dec 2025 14:19:49 +0300 Subject: [PATCH 1/8] fix: format bytes columns and avoid refetch on column toggle --- .../PaginatedTable/PaginatedTable.tsx | 3 ++ src/components/PaginatedTable/TableChunk.tsx | 10 +++++-- .../PaginatedTable/TableChunksRenderer.tsx | 4 +++ .../PaginatedTable/requestBatcher.ts | 2 +- src/components/PaginatedTable/types.ts | 2 +- .../nodesColumns/__test__/utils.test.ts | 2 +- .../Node/NodeNetwork/NodeNetworkTable.tsx | 1 + src/containers/Node/NodeNetwork/columns.ts | 6 ++-- src/containers/Nodes/getNodes.ts | 5 +++- .../PaginatedStorageGroupsTable/getGroups.ts | 2 +- .../PaginatedStorageNodesTable/getNodes.ts | 5 +++- src/store/reducers/tableData.ts | 2 +- .../bytesParsers/__test__/formatBytes.test.ts | 2 +- src/utils/bytesParsers/formatBytes.ts | 4 +-- src/utils/constants.ts | 2 ++ .../__test__/formatNumbers.test.ts | 2 +- .../__test__/formatStorageValues.test.ts | 2 +- .../__test__/formatUptime.test.ts | 2 +- src/utils/dataFormatters/dataFormatters.ts | 4 +-- src/utils/dataFormatters/formatNumber.ts | 3 +- src/utils/numeral.ts | 2 +- src/utils/utils.ts | 30 +++++++++++-------- 22 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/components/PaginatedTable/PaginatedTable.tsx b/src/components/PaginatedTable/PaginatedTable.tsx index 3cd5a3436f..9c348cffa0 100644 --- a/src/components/PaginatedTable/PaginatedTable.tsx +++ b/src/components/PaginatedTable/PaginatedTable.tsx @@ -33,6 +33,7 @@ export interface PaginatedTableProps { containerClassName?: string; onDataFetched?: (data: PaginatedTableData) => void; keepCache?: boolean; + useColumnsIdsInRequest?: boolean; } const DEFAULT_PAGINATION_LIMIT = 20; @@ -53,6 +54,7 @@ export const PaginatedTable = ({ containerClassName, onDataFetched, keepCache = true, + useColumnsIdsInRequest = true, }: PaginatedTableProps) => { // Get state and setters from context const {tableState, setSortParams, setTotalEntities, setFoundEntities, setIsInitialLoad} = @@ -122,6 +124,7 @@ export const PaginatedTable = ({ renderEmptyDataMessage={renderEmptyDataMessage} onDataFetched={handleDataFetched} keepCache={keepCache} + useColumnsIdsInRequest={useColumnsIdsInRequest} /> diff --git a/src/components/PaginatedTable/TableChunk.tsx b/src/components/PaginatedTable/TableChunk.tsx index e19632e5bd..4906c27aca 100644 --- a/src/components/PaginatedTable/TableChunk.tsx +++ b/src/components/PaginatedTable/TableChunk.tsx @@ -41,6 +41,7 @@ interface TableChunkProps { onDataFetched: (data?: PaginatedTableData) => void; keepCache?: boolean; + useColumnsIdsInRequest?: boolean; } // Memoisation prevents chunks rerenders that could cause perfomance issues on big tables @@ -61,13 +62,18 @@ export const TableChunk = typedMemo(function TableChunk({ shouldFetch, shouldRender, keepCache, + useColumnsIdsInRequest, }: TableChunkProps) { const [isTimeoutActive, setIsTimeoutActive] = React.useState(true); const [autoRefreshInterval] = useAutoRefreshInterval(); const {noBatching} = usePaginatedTableState(); - //sort ids to prevent refetch if only order was changed - const columnsIds = columns.map((column) => column.name).toSorted(); + const columnsIds = React.useMemo( + () => + //sort ids to prevent refetch if only order was changed + useColumnsIdsInRequest ? columns.map((column) => column.name).toSorted() : undefined, + [columns, useColumnsIdsInRequest], + ); const queryParams = { offset: id * chunkSize, diff --git a/src/components/PaginatedTable/TableChunksRenderer.tsx b/src/components/PaginatedTable/TableChunksRenderer.tsx index 0a1e7185d5..b78e328a69 100644 --- a/src/components/PaginatedTable/TableChunksRenderer.tsx +++ b/src/components/PaginatedTable/TableChunksRenderer.tsx @@ -29,6 +29,7 @@ export interface TableChunksRendererProps { renderEmptyDataMessage?: RenderEmptyDataMessage; onDataFetched: (data?: PaginatedTableData) => void; keepCache: boolean; + useColumnsIdsInRequest?: boolean; } export const TableChunksRenderer = ({ @@ -47,6 +48,7 @@ export const TableChunksRenderer = ({ renderEmptyDataMessage, onDataFetched, keepCache, + useColumnsIdsInRequest, }: TableChunksRendererProps) => { const chunkStates = useScrollBasedChunks({ scrollContainerRef, @@ -125,6 +127,7 @@ export const TableChunksRenderer = ({ shouldFetch={chunkState.shouldFetch} shouldRender={chunkState.shouldRender} keepCache={keepCache} + useColumnsIdsInRequest={useColumnsIdsInRequest} /> ); }, @@ -143,6 +146,7 @@ export const TableChunksRenderer = ({ rowHeight, sortParams, tableName, + useColumnsIdsInRequest, ], ); diff --git a/src/components/PaginatedTable/requestBatcher.ts b/src/components/PaginatedTable/requestBatcher.ts index 60cdadfc18..594ed8fd79 100644 --- a/src/components/PaginatedTable/requestBatcher.ts +++ b/src/components/PaginatedTable/requestBatcher.ts @@ -6,7 +6,7 @@ interface PaginatedTableParams { filters: F; limit: number; sortParams?: SortParams; - columnsIds: string[]; + columnsIds?: string[]; tableName: string; } diff --git a/src/components/PaginatedTable/types.ts b/src/components/PaginatedTable/types.ts index 63031186f9..c2b717482b 100644 --- a/src/components/PaginatedTable/types.ts +++ b/src/components/PaginatedTable/types.ts @@ -48,7 +48,7 @@ type FetchDataParams = { offset: number; filters?: F; sortParams?: SortParams; - columnsIds: string[]; + columnsIds?: string[]; signal?: AbortSignal; } & E; diff --git a/src/components/nodesColumns/__test__/utils.test.ts b/src/components/nodesColumns/__test__/utils.test.ts index b60ee5bfed..c109ba8317 100644 --- a/src/components/nodesColumns/__test__/utils.test.ts +++ b/src/components/nodesColumns/__test__/utils.test.ts @@ -1,4 +1,4 @@ -import {UNBREAKABLE_GAP} from '../../../utils/utils'; +import {UNBREAKABLE_GAP} from '../../../utils/constants'; import {prepareClockSkewValue, preparePingTimeValue} from '../utils'; describe('preparePingTimeValue', () => { diff --git a/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx b/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx index 2d656c63a7..ff91367c08 100644 --- a/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx +++ b/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx @@ -43,6 +43,7 @@ export function NodeNetworkTable({ fetchData={getNodePeers} filters={filters} tableName={i18n('table_node-peers')} + useColumnsIdsInRequest={false} renderErrorMessage={renderPaginatedTableErrorMessage} renderEmptyDataMessage={renderEmptyDataMessage} onDataFetched={onDataFetched} diff --git a/src/containers/Node/NodeNetwork/columns.ts b/src/containers/Node/NodeNetwork/columns.ts index 877eeff07d..e2bfc0b405 100644 --- a/src/containers/Node/NodeNetwork/columns.ts +++ b/src/containers/Node/NodeNetwork/columns.ts @@ -43,7 +43,7 @@ function getPeerSentBytesColumn(): Colu width: 140, resizeMinWidth: 120, render: ({row}) => - isNumeric(row.BytesSend) ? bytesToMB(row.BytesSend, 0) : EMPTY_DATA_PLACEHOLDER, + isNumeric(row.BytesSend) ? bytesToMB(row.BytesSend, 0, true) : EMPTY_DATA_PLACEHOLDER, }; } @@ -55,7 +55,9 @@ function getPeerReceivedBytesColumn width: 160, resizeMinWidth: 130, render: ({row}) => - isNumeric(row.BytesReceived) ? bytesToMB(row.BytesReceived, 0) : EMPTY_DATA_PLACEHOLDER, + isNumeric(row.BytesReceived) + ? bytesToMB(row.BytesReceived, 0, true) + : EMPTY_DATA_PLACEHOLDER, }; } diff --git a/src/containers/Nodes/getNodes.ts b/src/containers/Nodes/getNodes.ts index 391b5f0f2e..8a07fcad1d 100644 --- a/src/containers/Nodes/getNodes.ts +++ b/src/containers/Nodes/getNodes.ts @@ -36,7 +36,10 @@ export const getNodes: FetchData< const sortField = getNodesColumnSortField(columnId); const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; - const dataFieldsRequired = getRequiredDataFields(columnsIds, NODES_COLUMNS_TO_DATA_FIELDS); + const dataFieldsRequired = getRequiredDataFields( + columnsIds ?? Object.keys(NODES_COLUMNS_TO_DATA_FIELDS), + NODES_COLUMNS_TO_DATA_FIELDS, + ); const schemePathParam = !isNil(path) && !isNil(databaseFullPath) ? {path, databaseFullPath} : undefined; diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts b/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts index 0c99fa45fa..0f8786fc41 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts +++ b/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts @@ -33,7 +33,7 @@ export function useGroupsGetter(shouldUseGroupsHandler: boolean) { const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; const dataFieldsRequired = getRequiredDataFields( - columnsIds, + columnsIds ?? Object.keys(GROUPS_COLUMNS_TO_DATA_FIELDS), GROUPS_COLUMNS_TO_DATA_FIELDS, ); diff --git a/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts b/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts index c8cc7d7f59..cf6c787e86 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts +++ b/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts @@ -42,7 +42,10 @@ export const getStorageNodes: FetchData< const sortField = getNodesColumnSortField(columnId); const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; - const dataFieldsRequired = getRequiredDataFields(columnsIds, NODES_COLUMNS_TO_DATA_FIELDS); + const dataFieldsRequired = getRequiredDataFields( + columnsIds ?? Object.keys(NODES_COLUMNS_TO_DATA_FIELDS), + NODES_COLUMNS_TO_DATA_FIELDS, + ); const response = await window.api.viewer.getNodes({ type, diff --git a/src/store/reducers/tableData.ts b/src/store/reducers/tableData.ts index 447f06d739..cf74a26546 100644 --- a/src/store/reducers/tableData.ts +++ b/src/store/reducers/tableData.ts @@ -11,7 +11,7 @@ interface PaginatedTableParams { filters: F; limit: number; sortParams?: SortParams; - columnsIds: string[]; + columnsIds?: string[]; tableName: string; noBatching?: boolean; } diff --git a/src/utils/bytesParsers/__test__/formatBytes.test.ts b/src/utils/bytesParsers/__test__/formatBytes.test.ts index 11f6ff1e94..474387e4b3 100644 --- a/src/utils/bytesParsers/__test__/formatBytes.test.ts +++ b/src/utils/bytesParsers/__test__/formatBytes.test.ts @@ -1,4 +1,4 @@ -import {UNBREAKABLE_GAP} from '../../utils'; +import {UNBREAKABLE_GAP} from '../../constants'; import {formatBytes} from '../formatBytes'; describe('formatBytes', () => { diff --git a/src/utils/bytesParsers/formatBytes.ts b/src/utils/bytesParsers/formatBytes.ts index 6c22be3cf4..3be9116bd0 100644 --- a/src/utils/bytesParsers/formatBytes.ts +++ b/src/utils/bytesParsers/formatBytes.ts @@ -1,7 +1,7 @@ -import {GIGABYTE, KILOBYTE, MEGABYTE, TERABYTE} from '../constants'; +import {GIGABYTE, KILOBYTE, MEGABYTE, TERABYTE, UNBREAKABLE_GAP} from '../constants'; import type {FormatToSizeArgs, FormatValuesArgs} from '../dataFormatters/common'; import {formatNumber, roundToPrecision} from '../dataFormatters/dataFormatters'; -import {UNBREAKABLE_GAP, isNumeric} from '../utils'; +import {isNumeric} from '../utils'; import i18n from './i18n'; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 86d35e3dbf..e3fe921709 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -22,6 +22,8 @@ export const MS_IN_NANOSECONDS = 1000000; export const DEFAULT_WARNING_THRESHOLD = 85; export const DEFAULT_DANGER_THRESHOLD = 95; +export const UNBREAKABLE_GAP = '\xa0'; + const TABLET_SYMBOLS = { [EType.OldTxProxy]: 'P', [EType.TxProxy]: 'P', diff --git a/src/utils/dataFormatters/__test__/formatNumbers.test.ts b/src/utils/dataFormatters/__test__/formatNumbers.test.ts index a99bc528d1..d684ccb8a7 100644 --- a/src/utils/dataFormatters/__test__/formatNumbers.test.ts +++ b/src/utils/dataFormatters/__test__/formatNumbers.test.ts @@ -1,4 +1,4 @@ -import {UNBREAKABLE_GAP} from '../../utils'; +import {UNBREAKABLE_GAP} from '../../constants'; import {formatNumericValues} from '../dataFormatters'; describe('formatNumericValues', () => { diff --git a/src/utils/dataFormatters/__test__/formatStorageValues.test.ts b/src/utils/dataFormatters/__test__/formatStorageValues.test.ts index ea54a1d976..04bb4050a6 100644 --- a/src/utils/dataFormatters/__test__/formatStorageValues.test.ts +++ b/src/utils/dataFormatters/__test__/formatStorageValues.test.ts @@ -1,4 +1,4 @@ -import {UNBREAKABLE_GAP} from '../../utils'; +import {UNBREAKABLE_GAP} from '../../constants'; import {formatStorageValues} from '../dataFormatters'; describe('formatStorageValues', () => { diff --git a/src/utils/dataFormatters/__test__/formatUptime.test.ts b/src/utils/dataFormatters/__test__/formatUptime.test.ts index 8ad347c2f8..b1e28063d2 100644 --- a/src/utils/dataFormatters/__test__/formatUptime.test.ts +++ b/src/utils/dataFormatters/__test__/formatUptime.test.ts @@ -1,4 +1,4 @@ -import {UNBREAKABLE_GAP} from '../../utils'; +import {UNBREAKABLE_GAP} from '../../constants'; import { formatUptimeInSeconds, getDowntimeFromDateFormatted, diff --git a/src/utils/dataFormatters/dataFormatters.ts b/src/utils/dataFormatters/dataFormatters.ts index 2ee9adfd3f..856f1f2bed 100644 --- a/src/utils/dataFormatters/dataFormatters.ts +++ b/src/utils/dataFormatters/dataFormatters.ts @@ -3,9 +3,9 @@ import {dateTimeParse, duration} from '@gravity-ui/date-utils'; import type {TVDiskID, TVSlotId} from '../../types/api/vdisk'; import {formatBytes as formatBytesCustom, getBytesSizeUnit} from '../bytesParsers/formatBytes'; import type {BytesSizes} from '../bytesParsers/formatBytes'; -import {HOUR_IN_SECONDS} from '../constants'; +import {HOUR_IN_SECONDS, UNBREAKABLE_GAP} from '../constants'; import {configuredNumeral} from '../numeral'; -import {UNBREAKABLE_GAP, isNumeric} from '../utils'; +import {isNumeric} from '../utils'; import {formatValues} from './common'; import {formatNumberWithDigits, getNumberSizeUnit} from './formatNumber'; diff --git a/src/utils/dataFormatters/formatNumber.ts b/src/utils/dataFormatters/formatNumber.ts index c051a2c44a..9f57746184 100644 --- a/src/utils/dataFormatters/formatNumber.ts +++ b/src/utils/dataFormatters/formatNumber.ts @@ -1,5 +1,6 @@ import i18n from '../bytesParsers/i18n'; -import {UNBREAKABLE_GAP, isNumeric} from '../utils'; +import {UNBREAKABLE_GAP} from '../constants'; +import {isNumeric} from '../utils'; import type {FormatToSizeArgs, FormatValuesArgs} from './common'; import {formatNumber, roundToPrecision} from './dataFormatters'; diff --git a/src/utils/numeral.ts b/src/utils/numeral.ts index 1ae6acc13a..002f7e1430 100644 --- a/src/utils/numeral.ts +++ b/src/utils/numeral.ts @@ -1,8 +1,8 @@ import numeral from 'numeral'; import 'numeral/locales'; // Without this numeral will throw an error when using not 'en' locale +import {UNBREAKABLE_GAP} from './constants'; import {Lang, i18n} from './i18n'; -import {UNBREAKABLE_GAP} from './utils'; // Set space delimiter for all locales possible in project Object.values(Lang).forEach((value) => { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index d4440af83f..be2414d800 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,3 +1,5 @@ +import {formatNumber} from './dataFormatters/dataFormatters'; + export function parseJson(value?: string | null) { if (!value) { return undefined; @@ -31,7 +33,11 @@ export function bytesToSize(bytes: number) { return val.toPrecision(3) + sizes[i]; } -export function bytesToMB(bytes?: number | string, fractionDigits?: number) { +export function bytesToMB( + bytes?: number | string, + fractionDigits?: number, + withThousandsGrouping?: boolean, +) { const bytesNumber = Number(bytes); if (isNaN(bytesNumber)) { return ''; @@ -39,19 +45,21 @@ export function bytesToMB(bytes?: number | string, fractionDigits?: number) { const val = bytesNumber / base ** 2; - if (isNumeric(fractionDigits)) { - const rounded = Number(val.toFixed(fractionDigits)); + let rounded; - return String(rounded) + sizes[2]; - } - - if (val < 10) { - return val.toFixed(2) + sizes[2]; + if (isNumeric(fractionDigits)) { + rounded = val.toFixed(fractionDigits); + } else if (val < 10) { + rounded = val.toFixed(2); } else if (val < 100) { - return val.toFixed(1) + sizes[2]; + rounded = val.toFixed(1); } else { - return val.toFixed() + sizes[2]; + rounded = val.toFixed(); } + + const result = withThousandsGrouping ? formatNumber(rounded) : rounded; + + return `${result}${sizes[2]}`; } export function bytesToSpeed(bytes?: number | string, fractionDigits?: number) { @@ -104,8 +112,6 @@ export function toExponential(value: number, precision?: number) { return Number(value).toExponential(precision); } -export const UNBREAKABLE_GAP = '\xa0'; - // Numeric values expected, not numeric value should be displayd as 0 export function safeParseNumber(value: unknown, defaultValue = 0): number { if (isNumeric(value)) { From 1a28b1dbe5e47ff05d2fe3571c2bdbc4e75934f9 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Mon, 1 Dec 2025 14:59:58 +0300 Subject: [PATCH 2/8] Fix bugs --- .../MetricsTabs/components/PlaceholderTab.tsx | 6 ++-- src/utils/constants.ts | 4 +-- src/utils/utils.ts | 31 ++++++++++++------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/MetricsTabs/components/PlaceholderTab.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/MetricsTabs/components/PlaceholderTab.tsx index b1b13cc1e1..c5da545eb7 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/MetricsTabs/components/PlaceholderTab.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/MetricsTabs/components/PlaceholderTab.tsx @@ -1,5 +1,5 @@ import {cn} from '../../../../../../utils/cn'; -import {NON_BREAKING_SPACE} from '../../../../../../utils/constants'; +import {UNBREAKABLE_GAP} from '../../../../../../utils/constants'; import {ServerlessTabCard} from '../../TabCard/ServerlessTabCard'; import '../MetricsTabs.scss'; @@ -11,10 +11,10 @@ export function PlaceholderTab() {
diff --git a/src/utils/constants.ts b/src/utils/constants.ts index e3fe921709..e1b97ab4a6 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -22,8 +22,6 @@ export const MS_IN_NANOSECONDS = 1000000; export const DEFAULT_WARNING_THRESHOLD = 85; export const DEFAULT_DANGER_THRESHOLD = 95; -export const UNBREAKABLE_GAP = '\xa0'; - const TABLET_SYMBOLS = { [EType.OldTxProxy]: 'P', [EType.TxProxy]: 'P', @@ -70,7 +68,7 @@ export const SECTION_IDS = { export const TENANT_OVERVIEW_TABLES_LIMIT = 3; export const EMPTY_DATA_PLACEHOLDER = '—'; -export const NON_BREAKING_SPACE = '\u00A0'; +export const UNBREAKABLE_GAP = '\u00A0'; export const QUERY_TECHNICAL_MARK = '/*UI-QUERY-EXCLUDE*/'; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index be2414d800..dd1a74bca4 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -33,6 +33,23 @@ export function bytesToSize(bytes: number) { return val.toPrecision(3) + sizes[i]; } +function formatMbWithMaxFractionDigits(value: number, fractionDigits?: number): string { + if (isNumeric(fractionDigits)) { + const fixed = value.toFixed(fractionDigits); + const trimmed = fixed.replace(/\.?0+$/, ''); + + return trimmed === '' ? '0' : trimmed; + } + + if (value < 10) { + return value.toFixed(2); + } else if (value < 100) { + return value.toFixed(1); + } + + return value.toFixed(); +} + export function bytesToMB( bytes?: number | string, fractionDigits?: number, @@ -45,19 +62,9 @@ export function bytesToMB( const val = bytesNumber / base ** 2; - let rounded; - - if (isNumeric(fractionDigits)) { - rounded = val.toFixed(fractionDigits); - } else if (val < 10) { - rounded = val.toFixed(2); - } else if (val < 100) { - rounded = val.toFixed(1); - } else { - rounded = val.toFixed(); - } + const roundedStr = formatMbWithMaxFractionDigits(val, fractionDigits); - const result = withThousandsGrouping ? formatNumber(rounded) : rounded; + const result = withThousandsGrouping ? formatNumber(roundedStr) : roundedStr; return `${result}${sizes[2]}`; } From 61c41df806246f8f375ed49eb62c5dd4be406df8 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Mon, 1 Dec 2025 15:40:29 +0300 Subject: [PATCH 3/8] Fix bugs --- src/containers/Node/NodeNetwork/columns.ts | 18 +++++++---- src/utils/utils.ts | 37 +++++++--------------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/containers/Node/NodeNetwork/columns.ts b/src/containers/Node/NodeNetwork/columns.ts index e2bfc0b405..0408029816 100644 --- a/src/containers/Node/NodeNetwork/columns.ts +++ b/src/containers/Node/NodeNetwork/columns.ts @@ -12,9 +12,9 @@ import { } from '../../../components/nodesColumns/columns'; import type {GetNodesColumnsParams} from '../../../components/nodesColumns/types'; import {EMPTY_DATA_PLACEHOLDER} from '../../../lib'; +import {formatBytes} from '../../../utils/bytesParsers'; import {formatDateTime} from '../../../utils/dataFormatters/dataFormatters'; import type {Column} from '../../../utils/tableUtils/types'; -import {bytesToMB, isNumeric} from '../../../utils/utils'; import { NODE_NETWORK_COLUMNS_IDS, @@ -35,6 +35,14 @@ function getPeerConnectTimeColumn(): Column }; } +function renderSent(bytes?: number | string) { + return formatBytes({ + value: bytes, + size: 'mb', + withSizeLabel: true, + }); +} + function getPeerSentBytesColumn(): Column { return { name: NODE_NETWORK_COLUMNS_IDS.BytesSend, @@ -42,8 +50,7 @@ function getPeerSentBytesColumn(): Colu align: DataTable.RIGHT, width: 140, resizeMinWidth: 120, - render: ({row}) => - isNumeric(row.BytesSend) ? bytesToMB(row.BytesSend, 0, true) : EMPTY_DATA_PLACEHOLDER, + render: ({row}) => renderSent(row.BytesSend) ?? EMPTY_DATA_PLACEHOLDER, }; } @@ -54,10 +61,7 @@ function getPeerReceivedBytesColumn align: DataTable.RIGHT, width: 160, resizeMinWidth: 130, - render: ({row}) => - isNumeric(row.BytesReceived) - ? bytesToMB(row.BytesReceived, 0, true) - : EMPTY_DATA_PLACEHOLDER, + render: ({row}) => renderSent(row.BytesReceived) ?? EMPTY_DATA_PLACEHOLDER, }; } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 11b741e522..9d9f3d6704 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -34,28 +34,7 @@ export function bytesToSize(bytes: number) { return val.toPrecision(3) + sizes[i]; } -function formatMbWithMaxFractionDigits(value: number, fractionDigits?: number): string { - if (isNumeric(fractionDigits)) { - const fixed = value.toFixed(fractionDigits); - const trimmed = fixed.replace(/\.?0+$/, ''); - - return trimmed === '' ? '0' : trimmed; - } - - if (value < 10) { - return value.toFixed(2); - } else if (value < 100) { - return value.toFixed(1); - } - - return value.toFixed(); -} - -export function bytesToMB( - bytes?: number | string, - fractionDigits?: number, - withThousandsGrouping?: boolean, -) { +export function bytesToMB(bytes?: number | string, fractionDigits?: number) { const bytesNumber = Number(bytes); if (isNaN(bytesNumber)) { return ''; @@ -63,11 +42,19 @@ export function bytesToMB( const val = bytesNumber / base ** 2; - const roundedStr = formatMbWithMaxFractionDigits(val, fractionDigits); + if (isNumeric(fractionDigits)) { + const rounded = Number(val.toFixed(fractionDigits)); - const result = withThousandsGrouping ? formatNumber(roundedStr) : roundedStr; + return String(rounded) + sizes[2]; + } - return `${result}${sizes[2]}`; + if (val < 10) { + return val.toFixed(2) + sizes[2]; + } else if (val < 100) { + return val.toFixed(1) + sizes[2]; + } else { + return val.toFixed() + sizes[2]; + } } export function bytesToSpeed(bytes?: number | string, fractionDigits?: number) { From 7b285816ddee7aae38fb44922b204e5016119995 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Mon, 1 Dec 2025 16:39:18 +0300 Subject: [PATCH 4/8] Fix bugs --- src/components/PaginatedTable/TableChunk.tsx | 2 +- src/components/PaginatedTable/requestBatcher.ts | 2 +- src/components/PaginatedTable/types.ts | 2 +- src/containers/Nodes/getNodes.ts | 5 +---- .../Storage/PaginatedStorageGroupsTable/getGroups.ts | 2 +- .../Storage/PaginatedStorageNodesTable/getNodes.ts | 5 +---- src/store/reducers/tableData.ts | 2 +- 7 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/components/PaginatedTable/TableChunk.tsx b/src/components/PaginatedTable/TableChunk.tsx index 4906c27aca..77e70d320f 100644 --- a/src/components/PaginatedTable/TableChunk.tsx +++ b/src/components/PaginatedTable/TableChunk.tsx @@ -71,7 +71,7 @@ export const TableChunk = typedMemo(function TableChunk({ const columnsIds = React.useMemo( () => //sort ids to prevent refetch if only order was changed - useColumnsIdsInRequest ? columns.map((column) => column.name).toSorted() : undefined, + useColumnsIdsInRequest ? columns.map((column) => column.name).toSorted() : [], [columns, useColumnsIdsInRequest], ); diff --git a/src/components/PaginatedTable/requestBatcher.ts b/src/components/PaginatedTable/requestBatcher.ts index 594ed8fd79..60cdadfc18 100644 --- a/src/components/PaginatedTable/requestBatcher.ts +++ b/src/components/PaginatedTable/requestBatcher.ts @@ -6,7 +6,7 @@ interface PaginatedTableParams { filters: F; limit: number; sortParams?: SortParams; - columnsIds?: string[]; + columnsIds: string[]; tableName: string; } diff --git a/src/components/PaginatedTable/types.ts b/src/components/PaginatedTable/types.ts index c2b717482b..63031186f9 100644 --- a/src/components/PaginatedTable/types.ts +++ b/src/components/PaginatedTable/types.ts @@ -48,7 +48,7 @@ type FetchDataParams = { offset: number; filters?: F; sortParams?: SortParams; - columnsIds?: string[]; + columnsIds: string[]; signal?: AbortSignal; } & E; diff --git a/src/containers/Nodes/getNodes.ts b/src/containers/Nodes/getNodes.ts index 8a07fcad1d..eaf7aed201 100644 --- a/src/containers/Nodes/getNodes.ts +++ b/src/containers/Nodes/getNodes.ts @@ -36,10 +36,7 @@ export const getNodes: FetchData< const sortField = getNodesColumnSortField(columnId); const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; - const dataFieldsRequired = getRequiredDataFields( - columnsIds ?? Object.keys(NODES_COLUMNS_TO_DATA_FIELDS), - NODES_COLUMNS_TO_DATA_FIELDS, - ); + const dataFieldsRequired = getRequiredDataFields(columnsIds, NODES_COLUMNS_TO_DATA_FIELDS,); const schemePathParam = !isNil(path) && !isNil(databaseFullPath) ? {path, databaseFullPath} : undefined; diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts b/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts index 0f8786fc41..0c99fa45fa 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts +++ b/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts @@ -33,7 +33,7 @@ export function useGroupsGetter(shouldUseGroupsHandler: boolean) { const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; const dataFieldsRequired = getRequiredDataFields( - columnsIds ?? Object.keys(GROUPS_COLUMNS_TO_DATA_FIELDS), + columnsIds, GROUPS_COLUMNS_TO_DATA_FIELDS, ); diff --git a/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts b/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts index cf6c787e86..c8cc7d7f59 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts +++ b/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts @@ -42,10 +42,7 @@ export const getStorageNodes: FetchData< const sortField = getNodesColumnSortField(columnId); const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; - const dataFieldsRequired = getRequiredDataFields( - columnsIds ?? Object.keys(NODES_COLUMNS_TO_DATA_FIELDS), - NODES_COLUMNS_TO_DATA_FIELDS, - ); + const dataFieldsRequired = getRequiredDataFields(columnsIds, NODES_COLUMNS_TO_DATA_FIELDS); const response = await window.api.viewer.getNodes({ type, diff --git a/src/store/reducers/tableData.ts b/src/store/reducers/tableData.ts index cf74a26546..447f06d739 100644 --- a/src/store/reducers/tableData.ts +++ b/src/store/reducers/tableData.ts @@ -11,7 +11,7 @@ interface PaginatedTableParams { filters: F; limit: number; sortParams?: SortParams; - columnsIds?: string[]; + columnsIds: string[]; tableName: string; noBatching?: boolean; } From f29b4576a21e453c92870fa1e82dc2db6af6f404 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Mon, 1 Dec 2025 16:43:42 +0300 Subject: [PATCH 5/8] Fix bugs --- src/containers/Nodes/getNodes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Nodes/getNodes.ts b/src/containers/Nodes/getNodes.ts index eaf7aed201..391b5f0f2e 100644 --- a/src/containers/Nodes/getNodes.ts +++ b/src/containers/Nodes/getNodes.ts @@ -36,7 +36,7 @@ export const getNodes: FetchData< const sortField = getNodesColumnSortField(columnId); const sort = sortField ? prepareSortValue(sortField, sortOrder) : undefined; - const dataFieldsRequired = getRequiredDataFields(columnsIds, NODES_COLUMNS_TO_DATA_FIELDS,); + const dataFieldsRequired = getRequiredDataFields(columnsIds, NODES_COLUMNS_TO_DATA_FIELDS); const schemePathParam = !isNil(path) && !isNil(databaseFullPath) ? {path, databaseFullPath} : undefined; From a8deff04fc00e5b1b4090e70bb8e998ec9304bfe Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Mon, 1 Dec 2025 16:49:01 +0300 Subject: [PATCH 6/8] Fix bugs --- src/containers/Node/NodeNetwork/columns.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/Node/NodeNetwork/columns.ts b/src/containers/Node/NodeNetwork/columns.ts index 0408029816..bc7f0dae93 100644 --- a/src/containers/Node/NodeNetwork/columns.ts +++ b/src/containers/Node/NodeNetwork/columns.ts @@ -50,7 +50,7 @@ function getPeerSentBytesColumn(): Colu align: DataTable.RIGHT, width: 140, resizeMinWidth: 120, - render: ({row}) => renderSent(row.BytesSend) ?? EMPTY_DATA_PLACEHOLDER, + render: ({row}) => renderSent(row.BytesSend) || EMPTY_DATA_PLACEHOLDER, }; } @@ -61,7 +61,7 @@ function getPeerReceivedBytesColumn align: DataTable.RIGHT, width: 160, resizeMinWidth: 130, - render: ({row}) => renderSent(row.BytesReceived) ?? EMPTY_DATA_PLACEHOLDER, + render: ({row}) => renderSent(row.BytesReceived) || EMPTY_DATA_PLACEHOLDER, }; } From e9594dff1fb5a7b242566f2d9b08836823f294ff Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Tue, 2 Dec 2025 23:40:36 +0300 Subject: [PATCH 7/8] Fix bugs --- .../PaginatedTable/PaginatedTable.tsx | 6 ++--- src/components/PaginatedTable/TableChunk.tsx | 12 +++++----- .../PaginatedTable/TableChunksRenderer.tsx | 7 ++---- src/components/PaginatedTable/constants.ts | 22 +++++++++++++++++++ .../Node/NodeNetwork/NodeNetworkTable.tsx | 5 ++--- src/containers/Node/NodeNetwork/columns.ts | 6 ++--- src/containers/Node/NodeNetwork/i18n/en.json | 3 +-- src/containers/Nodes/NodesTable.tsx | 4 ++-- .../PaginatedStorageGroupsTable.tsx | 4 ++-- .../PaginatedStorageNodesTable.tsx | 4 ++-- .../Diagnostics/TopicData/TopicData.tsx | 3 ++- 11 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/components/PaginatedTable/PaginatedTable.tsx b/src/components/PaginatedTable/PaginatedTable.tsx index 9c348cffa0..562dbe6c3f 100644 --- a/src/components/PaginatedTable/PaginatedTable.tsx +++ b/src/components/PaginatedTable/PaginatedTable.tsx @@ -3,6 +3,7 @@ import React from 'react'; import {usePaginatedTableState} from './PaginatedTableContext'; import {TableChunksRenderer} from './TableChunksRenderer'; import {TableHead} from './TableHead'; +import type {PaginatedTableId} from './constants'; import {DEFAULT_TABLE_ROW_HEIGHT} from './constants'; import {b} from './shared'; import type { @@ -22,7 +23,7 @@ export interface PaginatedTableProps { initialEntitiesCount?: number; fetchData: FetchData; filters?: F; - tableName: string; + tableName: PaginatedTableId; columns: Column[]; getRowClassName?: GetRowClassName; rowHeight?: number; @@ -33,7 +34,6 @@ export interface PaginatedTableProps { containerClassName?: string; onDataFetched?: (data: PaginatedTableData) => void; keepCache?: boolean; - useColumnsIdsInRequest?: boolean; } const DEFAULT_PAGINATION_LIMIT = 20; @@ -54,7 +54,6 @@ export const PaginatedTable = ({ containerClassName, onDataFetched, keepCache = true, - useColumnsIdsInRequest = true, }: PaginatedTableProps) => { // Get state and setters from context const {tableState, setSortParams, setTotalEntities, setFoundEntities, setIsInitialLoad} = @@ -124,7 +123,6 @@ export const PaginatedTable = ({ renderEmptyDataMessage={renderEmptyDataMessage} onDataFetched={handleDataFetched} keepCache={keepCache} - useColumnsIdsInRequest={useColumnsIdsInRequest} /> diff --git a/src/components/PaginatedTable/TableChunk.tsx b/src/components/PaginatedTable/TableChunk.tsx index 77e70d320f..7d55e9fdb2 100644 --- a/src/components/PaginatedTable/TableChunk.tsx +++ b/src/components/PaginatedTable/TableChunk.tsx @@ -8,6 +8,8 @@ import {ResponseError} from '../Errors/ResponseError'; import {usePaginatedTableState} from './PaginatedTableContext'; import {EmptyTableRow, LoadingTableRow, TableRow} from './TableRow'; +import type {PaginatedTableId} from './constants'; +import {shouldSendColumnIds} from './constants'; import i18n from './i18n'; import type { Column, @@ -32,7 +34,7 @@ interface TableChunkProps { sortParams?: SortParams; shouldFetch: boolean; shouldRender: boolean; - tableName: string; + tableName: PaginatedTableId; fetchData: FetchData; getRowClassName?: GetRowClassName; @@ -41,7 +43,6 @@ interface TableChunkProps { onDataFetched: (data?: PaginatedTableData) => void; keepCache?: boolean; - useColumnsIdsInRequest?: boolean; } // Memoisation prevents chunks rerenders that could cause perfomance issues on big tables @@ -62,17 +63,18 @@ export const TableChunk = typedMemo(function TableChunk({ shouldFetch, shouldRender, keepCache, - useColumnsIdsInRequest, }: TableChunkProps) { const [isTimeoutActive, setIsTimeoutActive] = React.useState(true); const [autoRefreshInterval] = useAutoRefreshInterval(); const {noBatching} = usePaginatedTableState(); + const preserveColsOrderInRequest = shouldSendColumnIds(tableName); + const columnsIds = React.useMemo( () => //sort ids to prevent refetch if only order was changed - useColumnsIdsInRequest ? columns.map((column) => column.name).toSorted() : [], - [columns, useColumnsIdsInRequest], + preserveColsOrderInRequest ? columns.map((column) => column.name).toSorted() : [], + [columns, preserveColsOrderInRequest], ); const queryParams = { diff --git a/src/components/PaginatedTable/TableChunksRenderer.tsx b/src/components/PaginatedTable/TableChunksRenderer.tsx index b78e328a69..1f9eccfb60 100644 --- a/src/components/PaginatedTable/TableChunksRenderer.tsx +++ b/src/components/PaginatedTable/TableChunksRenderer.tsx @@ -1,6 +1,7 @@ import React from 'react'; import {TableChunk} from './TableChunk'; +import type {PaginatedTableId} from './constants'; import {b} from './shared'; import type { Column, @@ -22,14 +23,13 @@ export interface TableChunksRendererProps { columns: Column[]; fetchData: FetchData; filters?: F; - tableName: string; + tableName: PaginatedTableId; sortParams?: SortParams; getRowClassName?: GetRowClassName; renderErrorMessage?: RenderErrorMessage; renderEmptyDataMessage?: RenderEmptyDataMessage; onDataFetched: (data?: PaginatedTableData) => void; keepCache: boolean; - useColumnsIdsInRequest?: boolean; } export const TableChunksRenderer = ({ @@ -48,7 +48,6 @@ export const TableChunksRenderer = ({ renderEmptyDataMessage, onDataFetched, keepCache, - useColumnsIdsInRequest, }: TableChunksRendererProps) => { const chunkStates = useScrollBasedChunks({ scrollContainerRef, @@ -127,7 +126,6 @@ export const TableChunksRenderer = ({ shouldFetch={chunkState.shouldFetch} shouldRender={chunkState.shouldRender} keepCache={keepCache} - useColumnsIdsInRequest={useColumnsIdsInRequest} /> ); }, @@ -146,7 +144,6 @@ export const TableChunksRenderer = ({ rowHeight, sortParams, tableName, - useColumnsIdsInRequest, ], ); diff --git a/src/components/PaginatedTable/constants.ts b/src/components/PaginatedTable/constants.ts index 355d659333..233a1357ab 100644 --- a/src/components/PaginatedTable/constants.ts +++ b/src/components/PaginatedTable/constants.ts @@ -16,3 +16,25 @@ export const DEFAULT_REQUEST_TIMEOUT = 200; export const DEFAULT_TABLE_ROW_HEIGHT = 41; export const DEFAULT_INTERSECTION_OBSERVER_MARGIN = '100%'; + +export const PAGINATED_TABLE_IDS = { + NODES: 'nodes', + STORAGE_NODES: 'storage-nodes', + STORAGE_GROUPS: 'storage-groups', + TOPIC_DATA: 'topic-data', + NODE_PEERS: 'node-peers', +} as const; + +export type PaginatedTableId = (typeof PAGINATED_TABLE_IDS)[keyof typeof PAGINATED_TABLE_IDS]; + +export const PAGINATED_TABLE_COLUMN_IDS_IN_REQUEST: Record = { + [PAGINATED_TABLE_IDS.NODES]: true, + [PAGINATED_TABLE_IDS.STORAGE_NODES]: true, + [PAGINATED_TABLE_IDS.STORAGE_GROUPS]: true, + [PAGINATED_TABLE_IDS.TOPIC_DATA]: true, + [PAGINATED_TABLE_IDS.NODE_PEERS]: false, +}; + +export function shouldSendColumnIds(tableId: PaginatedTableId): boolean { + return PAGINATED_TABLE_COLUMN_IDS_IN_REQUEST[tableId] ?? false; +} diff --git a/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx b/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx index ff91367c08..1b28051713 100644 --- a/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx +++ b/src/containers/Node/NodeNetwork/NodeNetworkTable.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {ResizeablePaginatedTable} from '../../../components/PaginatedTable'; +import {PAGINATED_TABLE_IDS, ResizeablePaginatedTable} from '../../../components/PaginatedTable'; import type {PaginatedTableData} from '../../../components/PaginatedTable'; import {renderPaginatedTableErrorMessage} from '../../../utils/renderPaginatedTableErrorMessage'; import type {Column} from '../../../utils/tableUtils/types'; @@ -42,8 +42,7 @@ export function NodeNetworkTable({ columns={columns} fetchData={getNodePeers} filters={filters} - tableName={i18n('table_node-peers')} - useColumnsIdsInRequest={false} + tableName={PAGINATED_TABLE_IDS.NODE_PEERS} renderErrorMessage={renderPaginatedTableErrorMessage} renderEmptyDataMessage={renderEmptyDataMessage} onDataFetched={onDataFetched} diff --git a/src/containers/Node/NodeNetwork/columns.ts b/src/containers/Node/NodeNetwork/columns.ts index bc7f0dae93..0948d23cf7 100644 --- a/src/containers/Node/NodeNetwork/columns.ts +++ b/src/containers/Node/NodeNetwork/columns.ts @@ -35,7 +35,7 @@ function getPeerConnectTimeColumn(): Column }; } -function renderSent(bytes?: number | string) { +function renderBytes(bytes?: number | string) { return formatBytes({ value: bytes, size: 'mb', @@ -50,7 +50,7 @@ function getPeerSentBytesColumn(): Colu align: DataTable.RIGHT, width: 140, resizeMinWidth: 120, - render: ({row}) => renderSent(row.BytesSend) || EMPTY_DATA_PLACEHOLDER, + render: ({row}) => renderBytes(row.BytesSend) || EMPTY_DATA_PLACEHOLDER, }; } @@ -61,7 +61,7 @@ function getPeerReceivedBytesColumn align: DataTable.RIGHT, width: 160, resizeMinWidth: 130, - render: ({row}) => renderSent(row.BytesReceived) || EMPTY_DATA_PLACEHOLDER, + render: ({row}) => renderBytes(row.BytesReceived) || EMPTY_DATA_PLACEHOLDER, }; } diff --git a/src/containers/Node/NodeNetwork/i18n/en.json b/src/containers/Node/NodeNetwork/i18n/en.json index 095e982f0c..57e46872ba 100644 --- a/src/containers/Node/NodeNetwork/i18n/en.json +++ b/src/containers/Node/NodeNetwork/i18n/en.json @@ -4,6 +4,5 @@ "field_received-bytes": "Received Bytes", "alert_no-network-data": "No network data", "search-placeholder": "Search peers", - "field_peers": "Peers", - "table_node-peers": "Node Peers" + "field_peers": "Peers" } diff --git a/src/containers/Nodes/NodesTable.tsx b/src/containers/Nodes/NodesTable.tsx index 8728cb02e3..112b4e219f 100644 --- a/src/containers/Nodes/NodesTable.tsx +++ b/src/containers/Nodes/NodesTable.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {Illustration} from '../../components/Illustration'; import type {PaginatedTableData} from '../../components/PaginatedTable'; -import {ResizeablePaginatedTable} from '../../components/PaginatedTable'; +import {PAGINATED_TABLE_IDS, ResizeablePaginatedTable} from '../../components/PaginatedTable'; import {NODES_COLUMNS_WIDTH_LS_KEY} from '../../components/nodesColumns/constants'; import type {NodesColumn} from '../../components/nodesColumns/types'; import type {NodesFilters} from '../../store/reducers/nodes/types'; @@ -94,7 +94,7 @@ export function NodesTable({ renderEmptyDataMessage={renderEmptyDataMessage} getRowClassName={getRowClassName} filters={tableFilters} - tableName="nodes" + tableName={PAGINATED_TABLE_IDS.NODES} onDataFetched={onDataFetched} /> ); diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.tsx b/src/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.tsx index f75db20712..5b54a35ac5 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.tsx +++ b/src/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {LoaderWrapper} from '../../../components/LoaderWrapper/LoaderWrapper'; import type {RenderErrorMessage} from '../../../components/PaginatedTable'; -import {ResizeablePaginatedTable} from '../../../components/PaginatedTable'; +import {PAGINATED_TABLE_IDS, ResizeablePaginatedTable} from '../../../components/PaginatedTable'; import { useCapabilitiesLoaded, useStorageGroupsHandlerAvailable, @@ -103,7 +103,7 @@ export const PaginatedStorageGroupsTable = ({ renderErrorMessage={renderErrorMessage} renderEmptyDataMessage={renderEmptyDataMessage} filters={tableFilters} - tableName="storage-groups" + tableName={PAGINATED_TABLE_IDS.STORAGE_GROUPS} /> ); diff --git a/src/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.tsx b/src/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.tsx index 13650bc36a..eb0f5c9a18 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.tsx +++ b/src/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.tsx @@ -1,7 +1,7 @@ import React from 'react'; import type {PaginatedTableData, RenderErrorMessage} from '../../../components/PaginatedTable'; -import {ResizeablePaginatedTable} from '../../../components/PaginatedTable'; +import {PAGINATED_TABLE_IDS, ResizeablePaginatedTable} from '../../../components/PaginatedTable'; import type {NodesColumn} from '../../../components/nodesColumns/types'; import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants'; import type {PreparedStorageNode, VisibleEntities} from '../../../store/reducers/storage/types'; @@ -109,7 +109,7 @@ export const PaginatedStorageNodesTable = ({ renderEmptyDataMessage={renderEmptyDataMessage} getRowClassName={getRowUnavailableClassName} filters={tableFilters} - tableName="storage-nodes" + tableName={PAGINATED_TABLE_IDS.STORAGE_NODES} onDataFetched={onDataFetched} /> ); diff --git a/src/containers/Tenant/Diagnostics/TopicData/TopicData.tsx b/src/containers/Tenant/Diagnostics/TopicData/TopicData.tsx index 1163e5eb5f..86fb8dde5b 100644 --- a/src/containers/Tenant/Diagnostics/TopicData/TopicData.tsx +++ b/src/containers/Tenant/Diagnostics/TopicData/TopicData.tsx @@ -11,6 +11,7 @@ import {PageError} from '../../../../components/Errors/PageError/PageError'; import {Fullscreen} from '../../../../components/Fullscreen/Fullscreen'; import { DEFAULT_TABLE_ROW_HEIGHT, + PAGINATED_TABLE_IDS, ResizeablePaginatedTable, } from '../../../../components/PaginatedTable'; import {PaginatedTableWithLayout} from '../../../../components/PaginatedTable/PaginatedTableWithLayout'; @@ -354,7 +355,7 @@ export function TopicData({scrollContainerRef, path, database, databaseFullPath} renderErrorMessage={renderPaginatedTableErrorMessage} renderEmptyDataMessage={renderEmptyDataMessage} filters={tableFilters} - tableName="topicData" + tableName={PAGINATED_TABLE_IDS.TOPIC_DATA} rowHeight={DEFAULT_TABLE_ROW_HEIGHT} keepCache={false} getRowClassName={(row) => { From f08286b18ff85b599bdba0755ddbe73a5c1edfa2 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Wed, 3 Dec 2025 00:56:34 +0300 Subject: [PATCH 8/8] Fix naming --- src/components/PaginatedTable/TableChunk.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/PaginatedTable/TableChunk.tsx b/src/components/PaginatedTable/TableChunk.tsx index 7d55e9fdb2..bfe3ae4b4c 100644 --- a/src/components/PaginatedTable/TableChunk.tsx +++ b/src/components/PaginatedTable/TableChunk.tsx @@ -68,13 +68,13 @@ export const TableChunk = typedMemo(function TableChunk({ const [autoRefreshInterval] = useAutoRefreshInterval(); const {noBatching} = usePaginatedTableState(); - const preserveColsOrderInRequest = shouldSendColumnIds(tableName); + const hasColumnsIdsInRequest = shouldSendColumnIds(tableName); const columnsIds = React.useMemo( () => - //sort ids to prevent refetch if only order was changed - preserveColsOrderInRequest ? columns.map((column) => column.name).toSorted() : [], - [columns, preserveColsOrderInRequest], + // sort ids to prevent refetch if only order was changed + hasColumnsIdsInRequest ? columns.map((column) => column.name).toSorted() : [], + [columns, hasColumnsIdsInRequest], ); const queryParams = {