Skip to content

Commit

Permalink
fix: dynamic column width
Browse files Browse the repository at this point in the history
  • Loading branch information
astandrik committed Oct 2, 2024
1 parent 77b21c1 commit 81874d6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 53 deletions.
21 changes: 17 additions & 4 deletions src/components/QueryResultTable/QueryResultTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {Column, Settings} from '@gravity-ui/react-data-table';
import type {ColumnType, KeyValueRow} from '../../types/api/query';
import {cn} from '../../utils/cn';
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
import {getColumnType, getColumnWidthByType, prepareQueryResponse} from '../../utils/query';
import {getColumnType, prepareQueryResponse} from '../../utils/query';
import {isNumeric} from '../../utils/utils';
import type {ResizeableDataTableProps} from '../ResizeableDataTable/ResizeableDataTable';
import {ResizeableDataTable} from '../ResizeableDataTable/ResizeableDataTable';
Expand All @@ -25,17 +25,30 @@ const TABLE_SETTINGS: Settings = {

export const b = cn('ydb-query-result-table');

const prepareTypedColumns = (columns: ColumnType[]) => {
const WIDTH_PREDICTION_ROWS_COUNT = 100;
const MAX_COLUMN_WIDTH = 600;

const prepareTypedColumns = (columns: ColumnType[], data?: KeyValueRow[]) => {
if (!columns.length) {
return [];
}

const dataSlice = data?.slice(0, WIDTH_PREDICTION_ROWS_COUNT);

return columns.map(({name, type}) => {
const columnType = getColumnType(type);

const maxColumnContentLength =
dataSlice?.reduce(
(max, row) => Math.max(max, row[name] ? String(row[name]).length : max),
name.length,
) || name.length;

const headerPadding = columnType === 'number' ? 40 : 20;

const column: Column<KeyValueRow> = {
name,
width: getColumnWidthByType(type, name),
width: Math.min(maxColumnContentLength * 10 + headerPadding, MAX_COLUMN_WIDTH),
align: columnType === 'number' ? DataTable.RIGHT : DataTable.LEFT,
sortAccessor: (row) => {
const value = row[name];
Expand Down Expand Up @@ -83,7 +96,7 @@ export const QueryResultTable = (props: QueryResultTableProps) => {

const data = React.useMemo(() => prepareQueryResponse(rawData), [rawData]);
const columns = React.useMemo(() => {
return rawColumns ? prepareTypedColumns(rawColumns) : prepareGenericColumns(data);
return rawColumns ? prepareTypedColumns(rawColumns, data) : prepareGenericColumns(data);
}, [data, rawColumns]);
const settings = React.useMemo(
() => ({
Expand Down
50 changes: 1 addition & 49 deletions src/utils/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,9 @@ export const QUERY_SYNTAX = {
pg: 'pg',
} as const;

export const getYQLColumnType = (type: string): YQLType => {
return type.replace(/\?$/, '') as YQLType;
};

// eslint-disable-next-line complexity
export const getColumnType = (type: string) => {
switch (getYQLColumnType(type)) {
switch (type.replace(/\?$/, '')) {
case YQLType.Bool:
return 'boolean';
case YQLType.Int8:
Expand Down Expand Up @@ -138,50 +134,6 @@ export const getColumnType = (type: string) => {
}
};

const columnTypeToDefaultWidth: Record<YQLType, number> = {
// Numeric
[YQLType.Bool]: 80,
[YQLType.Int8]: 80,
[YQLType.Int16]: 90,
[YQLType.Int32]: 140,
[YQLType.Int64]: 220,
[YQLType.Uint8]: 80,
[YQLType.Uint16]: 90,
[YQLType.Uint32]: 140,
[YQLType.Uint64]: 220,
[YQLType.Float]: 120,
[YQLType.Double]: 220,
[YQLType.Decimal]: 220,

// String
[YQLType.String]: 240,
[YQLType.Utf8]: 240,
[YQLType.Json]: 340,
[YQLType.JsonDocument]: 340,
[YQLType.Yson]: 340,
[YQLType.Uuid]: 190,

// Date and time
[YQLType.Date]: 300,
[YQLType.Datetime]: 300,
[YQLType.Timestamp]: 300,
[YQLType.Interval]: 300,
[YQLType.TzDate]: 300,
[YQLType.TzDateTime]: 300,
[YQLType.TzTimestamp]: 300,
};

const COLUMN_DEFAULT_WIDTH = 200;

export const getColumnWidthByType = (type: string, columnName: string) => {
const yqlType = getYQLColumnType(type);

return Math.max(
columnTypeToDefaultWidth[yqlType] || COLUMN_DEFAULT_WIDTH,
columnName.length * 15,
);
};

/** parse response result from ArrayRow to KeyValueRow */
const parseModernResult = (rows: ArrayRow[], columns: ColumnType[]) => {
return rows.map((row) => {
Expand Down

0 comments on commit 81874d6

Please sign in to comment.