Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions src/components/PaginatedTable/PaginatedTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface PaginatedTableProps<T, F> {
containerClassName?: string;
onDataFetched?: (data: PaginatedTableData<T>) => void;
keepCache?: boolean;
useColumnsIdsInRequest?: boolean;
}

const DEFAULT_PAGINATION_LIMIT = 20;
Expand All @@ -53,6 +54,7 @@ export const PaginatedTable = <T, F>({
containerClassName,
onDataFetched,
keepCache = true,
useColumnsIdsInRequest = true,
}: PaginatedTableProps<T, F>) => {
// Get state and setters from context
const {tableState, setSortParams, setTotalEntities, setFoundEntities, setIsInitialLoad} =
Expand Down Expand Up @@ -122,6 +124,7 @@ export const PaginatedTable = <T, F>({
renderEmptyDataMessage={renderEmptyDataMessage}
onDataFetched={handleDataFetched}
keepCache={keepCache}
useColumnsIdsInRequest={useColumnsIdsInRequest}
/>
</tbody>
</table>
Expand Down
10 changes: 8 additions & 2 deletions src/components/PaginatedTable/TableChunk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface TableChunkProps<T, F> {
onDataFetched: (data?: PaginatedTableData<T>) => void;

keepCache?: boolean;
useColumnsIdsInRequest?: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest to name this prop something like "preserveColsOrderInRequest"

useColumnsIdsInRequest is

looks like hook name
doesnt explicitly state how they are actually used

}

// Memoisation prevents chunks rerenders that could cause perfomance issues on big tables
Expand All @@ -61,13 +62,18 @@ export const TableChunk = typedMemo(function TableChunk<T, F>({
shouldFetch,
shouldRender,
keepCache,
useColumnsIdsInRequest,
}: TableChunkProps<T, F>) {
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(
Copy link
Contributor

Choose a reason for hiding this comment

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

may be if !useColumnsIdsInRequest, columnsIds will be []? To avoid nullish coalescing in getNodes фтв getGroups

() =>
//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,
Expand Down
4 changes: 4 additions & 0 deletions src/components/PaginatedTable/TableChunksRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface TableChunksRendererProps<T, F> {
renderEmptyDataMessage?: RenderEmptyDataMessage;
onDataFetched: (data?: PaginatedTableData<T>) => void;
keepCache: boolean;
useColumnsIdsInRequest?: boolean;
}

export const TableChunksRenderer = <T, F>({
Expand All @@ -47,6 +48,7 @@ export const TableChunksRenderer = <T, F>({
renderEmptyDataMessage,
onDataFetched,
keepCache,
useColumnsIdsInRequest,
}: TableChunksRendererProps<T, F>) => {
const chunkStates = useScrollBasedChunks({
scrollContainerRef,
Expand Down Expand Up @@ -125,6 +127,7 @@ export const TableChunksRenderer = <T, F>({
shouldFetch={chunkState.shouldFetch}
shouldRender={chunkState.shouldRender}
keepCache={keepCache}
useColumnsIdsInRequest={useColumnsIdsInRequest}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently we pass useColumnsIdsInRequest down the components tree to determine fetch options

The question is - do we use the same entities table with and without useColumnsIdsInRequest simultenously?

If not - I suggest to move this to fetching logics

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I understood you correctly, you suggest not to pass the useColumnsIdsInRequest prop down the component tree, but instead decide whether to include columnsIds in the fetch options inside the fetching logic itself.
In my case most tables always use column IDs in the request, and the peers table never uses them. So I can do something like:
const shouldUseColumnsIds = tableName !== 'node-peers'; (or use a map of table names) directly in the fetching logic instead of passing a prop from the UI.

Is that what you meant?

/>
);
},
Expand All @@ -143,6 +146,7 @@ export const TableChunksRenderer = <T, F>({
rowHeight,
sortParams,
tableName,
useColumnsIdsInRequest,
],
);

Expand Down
2 changes: 1 addition & 1 deletion src/components/PaginatedTable/requestBatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface PaginatedTableParams<T, F> {
filters: F;
limit: number;
sortParams?: SortParams;
columnsIds: string[];
columnsIds?: string[];
tableName: string;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/PaginatedTable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type FetchDataParams<F, E = {}> = {
offset: number;
filters?: F;
sortParams?: SortParams;
columnsIds: string[];
columnsIds?: string[];
signal?: AbortSignal;
} & E;

Expand Down
2 changes: 1 addition & 1 deletion src/components/nodesColumns/__test__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {UNBREAKABLE_GAP} from '../../../utils/utils';
import {UNBREAKABLE_GAP} from '../../../utils/constants';
import {prepareClockSkewValue, preparePingTimeValue} from '../utils';

describe('preparePingTimeValue', () => {
Expand Down
1 change: 1 addition & 0 deletions src/containers/Node/NodeNetwork/NodeNetworkTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function NodeNetworkTable({
fetchData={getNodePeers}
filters={filters}
tableName={i18n('table_node-peers')}
useColumnsIdsInRequest={false}
renderErrorMessage={renderPaginatedTableErrorMessage}
renderEmptyDataMessage={renderEmptyDataMessage}
onDataFetched={onDataFetched}
Expand Down
6 changes: 4 additions & 2 deletions src/containers/Node/NodeNetwork/columns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function getPeerSentBytesColumn<T extends {BytesSend?: string | number}>(): 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,
};
}

Expand All @@ -55,7 +55,9 @@ function getPeerReceivedBytesColumn<T extends {BytesReceived?: string | number}>
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,
};
}

Expand Down
5 changes: 4 additions & 1 deletion src/containers/Nodes/getNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/store/reducers/tableData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface PaginatedTableParams<T, F> {
filters: F;
limit: number;
sortParams?: SortParams;
columnsIds: string[];
columnsIds?: string[];
tableName: string;
noBatching?: boolean;
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/bytesParsers/__test__/formatBytes.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {UNBREAKABLE_GAP} from '../../utils';
import {UNBREAKABLE_GAP} from '../../constants';
import {formatBytes} from '../formatBytes';

describe('formatBytes', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/utils/bytesParsers/formatBytes.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
2 changes: 2 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
2 changes: 1 addition & 1 deletion src/utils/dataFormatters/__test__/formatNumbers.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {UNBREAKABLE_GAP} from '../../utils';
import {UNBREAKABLE_GAP} from '../../constants';
import {formatNumericValues} from '../dataFormatters';

describe('formatNumericValues', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {UNBREAKABLE_GAP} from '../../utils';
import {UNBREAKABLE_GAP} from '../../constants';
import {formatStorageValues} from '../dataFormatters';

describe('formatStorageValues', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/dataFormatters/__test__/formatUptime.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {UNBREAKABLE_GAP} from '../../utils';
import {UNBREAKABLE_GAP} from '../../constants';
import {
formatUptimeInSeconds,
getDowntimeFromDateFormatted,
Expand Down
4 changes: 2 additions & 2 deletions src/utils/dataFormatters/dataFormatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
3 changes: 2 additions & 1 deletion src/utils/dataFormatters/formatNumber.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
2 changes: 1 addition & 1 deletion src/utils/numeral.ts
Original file line number Diff line number Diff line change
@@ -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) => {
Expand Down
30 changes: 18 additions & 12 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {formatNumber} from './dataFormatters/dataFormatters';

export function parseJson(value?: string | null) {
if (!value) {
return undefined;
Expand Down Expand Up @@ -31,27 +33,33 @@ 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 '';
}

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) {
Expand Down Expand Up @@ -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)) {
Expand Down
Loading