11import React from 'react' ;
2+ // Query result viewer with tab persistence functionality
23
34import type { Settings } from '@gravity-ui/react-data-table' ;
45import type { ControlGroupOption } from '@gravity-ui/uikit' ;
@@ -10,13 +11,14 @@ import {Illustration} from '../../../../components/Illustration';
1011import { LoaderWrapper } from '../../../../components/LoaderWrapper/LoaderWrapper' ;
1112import { QueryExecutionStatus } from '../../../../components/QueryExecutionStatus' ;
1213import { disableFullscreen } from '../../../../store/reducers/fullscreen' ;
14+ import { selectResultTab , setResultTab } from '../../../../store/reducers/query/query' ;
1315import type { QueryResult } from '../../../../store/reducers/query/types' ;
1416import type { ValueOf } from '../../../../types/common' ;
1517import type { QueryAction } from '../../../../types/store/query' ;
1618import { cn } from '../../../../utils/cn' ;
1719import { USE_SHOW_PLAN_SVG_KEY } from '../../../../utils/constants' ;
1820import { getStringifiedData } from '../../../../utils/dataFormatters/dataFormatters' ;
19- import { useSetting , useTypedDispatch } from '../../../../utils/hooks' ;
21+ import { useSetting , useTypedDispatch , useTypedSelector } from '../../../../utils/hooks' ;
2022import { PaneVisibilityToggleButtons } from '../../utils/paneVisibilityToggleHelpers' ;
2123import { QuerySettingsBanner } from '../QuerySettingsBanner/QuerySettingsBanner' ;
2224import { QueryStoppedBanner } from '../QueryStoppedBanner/QueryStoppedBanner' ;
@@ -98,27 +100,43 @@ export function QueryResultViewer({
98100 onExpandResults,
99101} : ExecuteResultProps ) {
100102 const dispatch = useTypedDispatch ( ) ;
103+ const selectedTabs = useTypedSelector ( selectResultTab ) ;
101104
102105 const isExecute = resultType === 'execute' ;
103106 const isExplain = resultType === 'explain' ;
104107
105108 const [ selectedResultSet , setSelectedResultSet ] = React . useState ( 0 ) ;
106- const [ activeSection , setActiveSection ] = React . useState < SectionID > ( ( ) => {
107- return isExecute ? RESULT_OPTIONS_IDS . result : RESULT_OPTIONS_IDS . schema ;
108- } ) ;
109109 const [ useShowPlanToSvg ] = useSetting < boolean > ( USE_SHOW_PLAN_SVG_KEY ) ;
110110
111+ // Get the saved tab for the current query type, or use default
112+ const getDefaultSection = ( ) : SectionID => {
113+ return isExecute ? RESULT_OPTIONS_IDS . result : RESULT_OPTIONS_IDS . schema ;
114+ } ;
115+
116+ const activeSection : SectionID = React . useMemo ( ( ) => {
117+ const savedTab = selectedTabs ?. [ resultType ] ;
118+ if ( savedTab ) {
119+ // Validate that the saved tab is valid for the current result type
120+ const validSections = isExecute ? EXECUTE_SECTIONS : EXPLAIN_SECTIONS ;
121+ if ( validSections . includes ( savedTab as SectionID ) ) {
122+ return savedTab as SectionID ;
123+ }
124+ }
125+ return getDefaultSection ( ) ;
126+ } , [ selectedTabs , resultType , isExecute ] ) ;
127+
111128 const { error, isLoading, data = { } } = result ;
112129 const { preparedPlan, simplifiedPlan, stats, resultSets, ast} = data ;
113130
114131 React . useEffect ( ( ) => {
115- if ( resultType === 'execute' && ! EXECUTE_SECTIONS . includes ( activeSection ) ) {
116- setActiveSection ( 'result' ) ;
117- }
118- if ( resultType === 'explain' && ! EXPLAIN_SECTIONS . includes ( activeSection ) ) {
119- setActiveSection ( 'schema' ) ;
120- }
121- } , [ activeSection , resultType ] ) ;
132+ return ( ) => {
133+ dispatch ( disableFullscreen ( ) ) ;
134+ } ;
135+ } , [ dispatch ] ) ;
136+
137+ const onSelectSection = ( value : SectionID ) => {
138+ dispatch ( setResultTab ( { queryType : resultType , tabId : value } ) ) ;
139+ } ;
122140
123141 const radioButtonOptions : ControlGroupOption < SectionID > [ ] = React . useMemo ( ( ) => {
124142 let sections : SectionID [ ] = [ ] ;
@@ -137,16 +155,6 @@ export function QueryResultViewer({
137155 } ) ;
138156 } , [ isExecute , isExplain ] ) ;
139157
140- React . useEffect ( ( ) => {
141- return ( ) => {
142- dispatch ( disableFullscreen ( ) ) ;
143- } ;
144- } , [ dispatch ] ) ;
145-
146- const onSelectSection = ( value : SectionID ) => {
147- setActiveSection ( value ) ;
148- } ;
149-
150158 const getStatsToCopy = ( ) => {
151159 switch ( activeSection ) {
152160 case RESULT_OPTIONS_IDS . result : {
0 commit comments