diff --git a/src/components/QueryResultTable/QueryResultTable.tsx b/src/components/QueryResultTable/QueryResultTable.tsx index ba44dc255..f0762a983 100644 --- a/src/components/QueryResultTable/QueryResultTable.tsx +++ b/src/components/QueryResultTable/QueryResultTable.tsx @@ -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'; @@ -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 = { 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]; @@ -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( () => ({ diff --git a/src/utils/query.ts b/src/utils/query.ts index 15fb35682..4da0f4044 100644 --- a/src/utils/query.ts +++ b/src/utils/query.ts @@ -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: @@ -138,50 +134,6 @@ export const getColumnType = (type: string) => { } }; -const columnTypeToDefaultWidth: Record = { - // 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) => {