@@ -2,7 +2,10 @@ import React from 'react';
22
33import type { Column } from '@gravity-ui/react-data-table' ;
44import { TableColumnSetup } from '@gravity-ui/uikit' ;
5+ import { isEqual } from 'lodash' ;
56
7+ import { DrawerWrapper } from '../../../../components/Drawer' ;
8+ import { DrawerControlType } from '../../../../components/Drawer/Drawer' ;
69import { ResponseError } from '../../../../components/Errors/ResponseError' ;
710import { ResizeableDataTable } from '../../../../components/ResizeableDataTable/ResizeableDataTable' ;
811import { Search } from '../../../../components/Search' ;
@@ -14,6 +17,7 @@ import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks'
1417import { useSelectedColumns } from '../../../../utils/hooks/useSelectedColumns' ;
1518import { parseQueryErrorToString } from '../../../../utils/query' ;
1619
20+ import { QueryDetailsDrawerContent } from './QueryDetails/QueryDetailsDrawerContent' ;
1721import { getRunningQueriesColumns } from './columns/columns' ;
1822import {
1923 DEFAULT_RUNNING_QUERIES_COLUMNS ,
@@ -31,18 +35,19 @@ const b = cn('kv-top-queries');
3135interface RunningQueriesDataProps {
3236 tenantName : string ;
3337 renderQueryModeControl : ( ) => React . ReactNode ;
34- onRowClick : ( query : string ) => void ;
3538 handleTextSearchUpdate : ( text : string ) => void ;
3639}
3740
3841export const RunningQueriesData = ( {
3942 tenantName,
4043 renderQueryModeControl,
41- onRowClick,
4244 handleTextSearchUpdate,
4345} : RunningQueriesDataProps ) => {
4446 const [ autoRefreshInterval ] = useAutoRefreshInterval ( ) ;
4547 const filters = useTypedSelector ( ( state ) => state . executeTopQueries ) ;
48+ // Internal state for selected row
49+ // null is reserved for not found state
50+ const [ selectedRow , setSelectedRow ] = React . useState < KeyValueRow | null | undefined > ( undefined ) ;
4651
4752 // Get columns for running queries
4853 const columns : Column < KeyValueRow > [ ] = React . useMemo ( ( ) => {
@@ -70,44 +75,90 @@ export const RunningQueriesData = ({
7075 { pollingInterval : autoRefreshInterval } ,
7176 ) ;
7277
73- const handleRowClick = ( row : KeyValueRow ) => {
74- return onRowClick ( row . QueryText as string ) ;
75- } ;
78+ const rows = data ?. resultSets ?. [ 0 ] ?. result ;
79+
80+ const isDrawerVisible = selectedRow !== undefined ;
81+
82+ const handleCloseDetails = React . useCallback ( ( ) => {
83+ setSelectedRow ( undefined ) ;
84+ } , [ setSelectedRow ] ) ;
85+
86+ const renderDrawerContent = React . useCallback ( ( ) => {
87+ if ( ! isDrawerVisible ) {
88+ return null ;
89+ }
90+ return < QueryDetailsDrawerContent row = { selectedRow } onClose = { handleCloseDetails } /> ;
91+ } , [ isDrawerVisible , selectedRow , handleCloseDetails ] ) ;
92+
93+ const onRowClick = React . useCallback (
94+ (
95+ row : KeyValueRow | null ,
96+ _index ?: number ,
97+ event ?: React . MouseEvent < HTMLTableRowElement > ,
98+ ) => {
99+ event ?. stopPropagation ( ) ;
100+ setSelectedRow ( row ) ;
101+ } ,
102+ [ setSelectedRow ] ,
103+ ) ;
104+
105+ const inputRef = React . useRef < HTMLInputElement > ( null ) ;
106+
107+ React . useEffect ( ( ) => {
108+ if ( isDrawerVisible ) {
109+ inputRef . current ?. blur ( ) ;
110+ }
111+ } , [ isDrawerVisible ] ) ;
112+
113+ const drawerControls = React . useMemo ( ( ) => [ { type : DrawerControlType . CLOSE } as const ] , [ ] ) ;
76114
77115 return (
78- < TableWithControlsLayout >
79- < TableWithControlsLayout . Controls >
80- { renderQueryModeControl ( ) }
81- < Search
82- value = { filters . text }
83- onChange = { handleTextSearchUpdate }
84- placeholder = { i18n ( 'filter.text.placeholder' ) }
85- className = { b ( 'search' ) }
86- />
87- < TableColumnSetup
88- popupWidth = { 200 }
89- items = { columnsToSelect }
90- showStatus
91- onUpdate = { setColumns }
92- sortable = { false }
93- />
94- </ TableWithControlsLayout . Controls >
95-
96- { error ? < ResponseError error = { parseQueryErrorToString ( error ) } /> : null }
97- < TableWithControlsLayout . Table loading = { isLoading } >
98- < ResizeableDataTable
99- emptyDataMessage = { i18n ( 'no-data' ) }
100- columnsWidthLSKey = { RUNNING_QUERIES_COLUMNS_WIDTH_LS_KEY }
101- columns = { columnsToShow }
102- data = { data ?. resultSets ?. [ 0 ] . result || [ ] }
103- loading = { isFetching && currentData === undefined }
104- settings = { TOP_QUERIES_TABLE_SETTINGS }
105- onRowClick = { handleRowClick }
106- rowClassName = { ( ) => b ( 'row' ) }
107- sortOrder = { tableSort }
108- onSort = { handleTableSort }
109- />
110- </ TableWithControlsLayout . Table >
111- </ TableWithControlsLayout >
116+ < DrawerWrapper
117+ isDrawerVisible = { isDrawerVisible }
118+ onCloseDrawer = { handleCloseDetails }
119+ renderDrawerContent = { renderDrawerContent }
120+ drawerId = "running-query-details"
121+ storageKey = "running-queries-drawer-width"
122+ detectClickOutside
123+ isPercentageWidth
124+ title = { i18n ( 'query-details.title' ) }
125+ drawerControls = { drawerControls }
126+ >
127+ < TableWithControlsLayout >
128+ < TableWithControlsLayout . Controls >
129+ { renderQueryModeControl ( ) }
130+ < Search
131+ value = { filters . text }
132+ onChange = { handleTextSearchUpdate }
133+ placeholder = { i18n ( 'filter.text.placeholder' ) }
134+ className = { b ( 'search' ) }
135+ inputRef = { inputRef }
136+ />
137+ < TableColumnSetup
138+ popupWidth = { 200 }
139+ items = { columnsToSelect }
140+ showStatus
141+ onUpdate = { setColumns }
142+ sortable = { false }
143+ />
144+ </ TableWithControlsLayout . Controls >
145+
146+ { error ? < ResponseError error = { parseQueryErrorToString ( error ) } /> : null }
147+ < TableWithControlsLayout . Table loading = { isLoading } >
148+ < ResizeableDataTable
149+ emptyDataMessage = { i18n ( 'no-data' ) }
150+ columnsWidthLSKey = { RUNNING_QUERIES_COLUMNS_WIDTH_LS_KEY }
151+ columns = { columnsToShow }
152+ data = { rows || [ ] }
153+ loading = { isFetching && currentData === undefined }
154+ settings = { TOP_QUERIES_TABLE_SETTINGS }
155+ onRowClick = { onRowClick }
156+ rowClassName = { ( row ) => b ( 'row' , { active : isEqual ( row , selectedRow ) } ) }
157+ sortOrder = { tableSort }
158+ onSort = { handleTableSort }
159+ />
160+ </ TableWithControlsLayout . Table >
161+ </ TableWithControlsLayout >
162+ </ DrawerWrapper >
112163 ) ;
113164} ;
0 commit comments