1
1
import React from 'react' ;
2
2
3
+ import type { ControlGroupOption } from '@gravity-ui/uikit' ;
3
4
import { RadioButton , Tabs } from '@gravity-ui/uikit' ;
4
5
import JSONTree from 'react-json-inspector' ;
5
6
6
7
import { ClipboardButton } from '../../../../components/ClipboardButton' ;
7
8
import Divider from '../../../../components/Divider/Divider' ;
8
9
import EnableFullscreenButton from '../../../../components/EnableFullscreenButton/EnableFullscreenButton' ;
9
10
import Fullscreen from '../../../../components/Fullscreen/Fullscreen' ;
11
+ import { YDBGraph } from '../../../../components/Graph/Graph' ;
10
12
import { QueryExecutionStatus } from '../../../../components/QueryExecutionStatus' ;
11
13
import { QueryResultTable } from '../../../../components/QueryResultTable/QueryResultTable' ;
12
14
import { disableFullscreen } from '../../../../store/reducers/fullscreen' ;
@@ -22,51 +24,59 @@ import {ResultIssues} from '../Issues/Issues';
22
24
import { QueryDuration } from '../QueryDuration/QueryDuration' ;
23
25
import { getPreparedResult } from '../utils/getPreparedResult' ;
24
26
27
+ import { getPlan } from './utils' ;
28
+
25
29
import './ExecuteResult.scss' ;
26
30
27
31
const b = cn ( 'ydb-query-execute-result' ) ;
28
32
29
33
const resultOptionsIds = {
30
34
result : 'result' ,
31
35
stats : 'stats' ,
36
+ schema : 'schema' ,
32
37
} as const ;
33
38
34
39
type SectionID = ValueOf < typeof resultOptionsIds > ;
35
40
36
- const resultOptions = [
37
- { value : resultOptionsIds . result , content : 'Result' } ,
38
- { value : resultOptionsIds . stats , content : 'Stats' } ,
39
- ] ;
40
-
41
41
interface ExecuteResultProps {
42
42
data : IQueryResult | undefined ;
43
- stats : IQueryResult [ 'stats' ] | undefined ;
44
43
error : unknown ;
45
44
isResultsCollapsed ?: boolean ;
46
45
onCollapseResults : VoidFunction ;
47
46
onExpandResults : VoidFunction ;
47
+ theme ?: string ;
48
48
}
49
49
50
50
export function ExecuteResult ( {
51
51
data,
52
- stats,
53
52
error,
54
53
isResultsCollapsed,
55
54
onCollapseResults,
56
55
onExpandResults,
56
+ theme,
57
57
} : ExecuteResultProps ) {
58
58
const [ selectedResultSet , setSelectedResultSet ] = React . useState ( 0 ) ;
59
59
const [ activeSection , setActiveSection ] = React . useState < SectionID > ( resultOptionsIds . result ) ;
60
60
61
61
const isFullscreen = useTypedSelector ( ( state ) => state . fullscreen ) ;
62
62
const dispatch = useTypedDispatch ( ) ;
63
63
64
+ const stats = data ?. stats ;
64
65
const resultsSetsCount = data ?. resultSets ?. length ;
65
66
const isMulti = resultsSetsCount && resultsSetsCount > 0 ;
66
67
const currentResult = isMulti ? data ?. resultSets ?. [ selectedResultSet ] . result : data ?. result ;
67
68
const currentColumns = isMulti ? data ?. resultSets ?. [ selectedResultSet ] . columns : data ?. columns ;
68
69
const textResults = getPreparedResult ( currentResult ) ;
69
70
const copyDisabled = ! textResults . length ;
71
+ const plan = React . useMemo ( ( ) => getPlan ( data ) , [ data ] ) ;
72
+
73
+ const resultOptions : ControlGroupOption < SectionID > [ ] = [
74
+ { value : resultOptionsIds . result , content : 'Result' } ,
75
+ { value : resultOptionsIds . stats , content : 'Stats' } ,
76
+ ] ;
77
+ if ( plan ) {
78
+ resultOptions . push ( { value : resultOptionsIds . schema , content : 'Schema' } ) ;
79
+ }
70
80
71
81
const parsedError = parseQueryError ( error ) ;
72
82
@@ -145,6 +155,27 @@ export function ExecuteResult({
145
155
) ;
146
156
} ;
147
157
158
+ const renderSchema = ( ) => {
159
+ const isEnoughDataForGraph = plan ?. links && plan ?. nodes && plan ?. nodes . length ;
160
+
161
+ const content = isEnoughDataForGraph ? (
162
+ < div className = { b ( 'explain-canvas-container' ) } >
163
+ < YDBGraph key = { theme } data = { plan } />
164
+ </ div >
165
+ ) : null ;
166
+
167
+ return (
168
+ < React . Fragment >
169
+ { ! isFullscreen && content }
170
+ { isFullscreen && (
171
+ < Fullscreen >
172
+ < div className = { b ( 'result-fullscreen-wrapper' ) } > { content } </ div >
173
+ </ Fullscreen >
174
+ ) }
175
+ </ React . Fragment >
176
+ ) ;
177
+ } ;
178
+
148
179
const renderResult = ( ) => {
149
180
const content = renderContent ( ) ;
150
181
@@ -190,6 +221,10 @@ export function ExecuteResult({
190
221
return renderResult ( ) ;
191
222
}
192
223
224
+ if ( activeSection === resultOptionsIds . schema && ! error ) {
225
+ return renderSchema ( ) ;
226
+ }
227
+
193
228
return (
194
229
< div className = { b ( 'result' ) } >
195
230
{ activeSection === resultOptionsIds . stats && ! error && renderStats ( ) }
0 commit comments