Skip to content

Commit ce3435f

Browse files
Copilotadameat
andcommitted
Add Redux state to persist selected tab between query executions
Co-authored-by: adameat <[email protected]>
1 parent 310514f commit ce3435f

File tree

3 files changed

+45
-21
lines changed

3 files changed

+45
-21
lines changed

src/containers/Tenant/Query/QueryResult/QueryResultViewer.tsx

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ import {Illustration} from '../../../../components/Illustration';
1010
import {LoaderWrapper} from '../../../../components/LoaderWrapper/LoaderWrapper';
1111
import {QueryExecutionStatus} from '../../../../components/QueryExecutionStatus';
1212
import {disableFullscreen} from '../../../../store/reducers/fullscreen';
13+
import {selectResultTab, setResultTab} from '../../../../store/reducers/query/query';
1314
import type {QueryResult} from '../../../../store/reducers/query/types';
1415
import type {ValueOf} from '../../../../types/common';
1516
import type {QueryAction} from '../../../../types/store/query';
1617
import {cn} from '../../../../utils/cn';
1718
import {USE_SHOW_PLAN_SVG_KEY} from '../../../../utils/constants';
1819
import {getStringifiedData} from '../../../../utils/dataFormatters/dataFormatters';
19-
import {useSetting, useTypedDispatch} from '../../../../utils/hooks';
20+
import {useSetting, useTypedDispatch, useTypedSelector} from '../../../../utils/hooks';
2021
import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
2122
import {QuerySettingsBanner} from '../QuerySettingsBanner/QuerySettingsBanner';
2223
import {QueryStoppedBanner} from '../QueryStoppedBanner/QueryStoppedBanner';
@@ -98,27 +99,43 @@ export function QueryResultViewer({
9899
onExpandResults,
99100
}: ExecuteResultProps) {
100101
const dispatch = useTypedDispatch();
102+
const selectedTabs = useTypedSelector(selectResultTab);
101103

102104
const isExecute = resultType === 'execute';
103105
const isExplain = resultType === 'explain';
104106

105107
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-
});
109108
const [useShowPlanToSvg] = useSetting<boolean>(USE_SHOW_PLAN_SVG_KEY);
110109

110+
// Get the saved tab for the current query type, or use default
111+
const getDefaultSection = (): SectionID => {
112+
return isExecute ? RESULT_OPTIONS_IDS.result : RESULT_OPTIONS_IDS.schema;
113+
};
114+
115+
const activeSection: SectionID = React.useMemo(() => {
116+
const savedTab = selectedTabs?.[resultType];
117+
if (savedTab) {
118+
// Validate that the saved tab is valid for the current result type
119+
const validSections = isExecute ? EXECUTE_SECTIONS : EXPLAIN_SECTIONS;
120+
if (validSections.includes(savedTab as SectionID)) {
121+
return savedTab as SectionID;
122+
}
123+
}
124+
return getDefaultSection();
125+
}, [selectedTabs, resultType, isExecute]);
126+
111127
const {error, isLoading, data = {}} = result;
112128
const {preparedPlan, simplifiedPlan, stats, resultSets, ast} = data;
113129

114130
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]);
131+
return () => {
132+
dispatch(disableFullscreen());
133+
};
134+
}, [dispatch]);
135+
136+
const onSelectSection = (value: SectionID) => {
137+
dispatch(setResultTab({queryType: resultType, tabId: value}));
138+
};
122139

123140
const radioButtonOptions: ControlGroupOption<SectionID>[] = React.useMemo(() => {
124141
let sections: SectionID[] = [];
@@ -137,16 +154,6 @@ export function QueryResultViewer({
137154
});
138155
}, [isExecute, isExplain]);
139156

140-
React.useEffect(() => {
141-
return () => {
142-
dispatch(disableFullscreen());
143-
};
144-
}, [dispatch]);
145-
146-
const onSelectSection = (value: SectionID) => {
147-
setActiveSection(value);
148-
};
149-
150157
const getStatsToCopy = () => {
151158
switch (activeSection) {
152159
case RESULT_OPTIONS_IDS.result: {

src/store/reducers/query/query.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ const slice = createSlice({
128128
setQueryHistoryFilter: (state, action: PayloadAction<string>) => {
129129
state.history.filter = action.payload;
130130
},
131+
setResultTab: (
132+
state,
133+
action: PayloadAction<{queryType: 'execute' | 'explain'; tabId: string}>,
134+
) => {
135+
const {queryType, tabId} = action.payload;
136+
if (!state.selectedResultTab) {
137+
state.selectedResultTab = {};
138+
}
139+
state.selectedResultTab[queryType] = tabId;
140+
},
131141
setStreamSession: setStreamSessionReducer,
132142
addStreamingChunks: addStreamingChunksReducer,
133143
setStreamQueryResponse: setStreamQueryResponseReducer,
@@ -149,6 +159,7 @@ const slice = createSlice({
149159
selectUserInput: (state) => state.input,
150160
selectIsDirty: (state) => state.isDirty,
151161
selectQueriesHistoryCurrentIndex: (state) => state.history?.currentIndex,
162+
selectResultTab: (state) => state.selectedResultTab,
152163
},
153164
});
154165

@@ -177,6 +188,7 @@ export const {
177188
setStreamQueryResponse,
178189
setStreamSession,
179190
setIsDirty,
191+
setResultTab,
180192
} = slice.actions;
181193

182194
export const {
@@ -187,6 +199,7 @@ export const {
187199
selectResult,
188200
selectUserInput,
189201
selectIsDirty,
202+
selectResultTab,
190203
} = slice.selectors;
191204

192205
interface SendQueryParams extends QueryRequestParams {

src/store/reducers/query/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,8 @@ export interface QueryState {
6868
filter?: string;
6969
};
7070
tenantPath?: string;
71+
selectedResultTab?: {
72+
execute?: string;
73+
explain?: string;
74+
};
7175
}

0 commit comments

Comments
 (0)