@@ -2,6 +2,7 @@ import React from 'react';
22
33import DataTable from '@gravity-ui/react-data-table' ;
44import type { Column , Settings } from '@gravity-ui/react-data-table' ;
5+ import { ClipboardButton } from '@gravity-ui/uikit' ;
56
67import type { ColumnType , KeyValueRow } from '../../types/api/query' ;
78import { cn } from '../../utils/cn' ;
@@ -28,32 +29,49 @@ export const b = cn('ydb-query-result-table');
2829
2930const WIDTH_PREDICTION_ROWS_COUNT = 100 ;
3031
32+ //helper function to convert a row to TSV format for copying to clipboard
33+ const rowToTsv = ( row : KeyValueRow ) =>
34+ Object . values ( row )
35+ . map ( ( v ) => ( typeof v === 'object' ? JSON . stringify ( v ) : String ( v ) ) )
36+ . join ( '\t' ) ;
37+
3138const prepareTypedColumns = ( columns : ColumnType [ ] , data : KeyValueRow [ ] | undefined ) => {
3239 if ( ! columns . length ) {
3340 return [ ] ;
3441 }
3542
3643 const dataSlice = data ?. slice ( 0 , WIDTH_PREDICTION_ROWS_COUNT ) ;
3744
38- return columns . map ( ( { name, type} ) => {
45+ const dataColumns = columns . map ( ( { name, type} ) => {
3946 const columnType = getColumnType ( type ) ;
4047
4148 const column : Column < KeyValueRow > = {
4249 name,
4350 width : getColumnWidth ( { data : dataSlice , name} ) ,
4451 align : columnType === 'number' ? DataTable . RIGHT : DataTable . LEFT ,
4552 render : ( { row} ) => {
46- const data = row [ name ] ;
53+ const rowData = row [ name ] ;
4754 const normalizedData =
4855 columnType === 'binary-string' && typeof data === 'string'
49- ? JSON . stringify ( data ) . slice ( 1 , - 1 )
50- : String ( data ) ;
56+ ? JSON . stringify ( rowData ) . slice ( 1 , - 1 )
57+ : String ( rowData ) ;
5158 return < Cell value = { normalizedData } /> ;
5259 } ,
5360 } ;
5461
5562 return column ;
5663 } ) ;
64+
65+ const copyColumn : Column < KeyValueRow > = {
66+ name : 'copy' ,
67+ header : '' ,
68+ width : 40 ,
69+ render : ( { row} ) => (
70+ < ClipboardButton text = { rowToTsv ( row ) } view = "flat-secondary" size = "s" title = "Copy row" />
71+ ) ,
72+ } ;
73+
74+ return [ ...dataColumns , copyColumn ] ;
5775} ;
5876
5977const prepareGenericColumns = ( data : KeyValueRow [ ] | undefined ) => {
@@ -63,7 +81,7 @@ const prepareGenericColumns = (data: KeyValueRow[] | undefined) => {
6381
6482 const dataSlice = data ?. slice ( 0 , WIDTH_PREDICTION_ROWS_COUNT ) ;
6583
66- return Object . keys ( data [ 0 ] ) . map ( ( name ) => {
84+ const dataColumns = Object . keys ( data [ 0 ] ) . map ( ( name ) => {
6785 const column : Column < KeyValueRow > = {
6886 name,
6987 width : getColumnWidth ( { data : dataSlice , name} ) ,
@@ -73,6 +91,17 @@ const prepareGenericColumns = (data: KeyValueRow[] | undefined) => {
7391
7492 return column ;
7593 } ) ;
94+
95+ const copyColumn : Column < KeyValueRow > = {
96+ name : 'copy' ,
97+ header : '' ,
98+ width : 40 ,
99+ render : ( { row} ) => (
100+ < ClipboardButton text = { rowToTsv ( row ) } view = "flat-secondary" size = "s" title = "Copy row" />
101+ ) ,
102+ } ;
103+
104+ return [ ...dataColumns , copyColumn ] ;
76105} ;
77106
78107const getRowIndex = ( _ : unknown , index : number ) => index ;
0 commit comments