Skip to content

Commit d1d64f7

Browse files
authored
fix: unsaved changes in query editor (#2026)
1 parent 7af1ed3 commit d1d64f7

File tree

16 files changed

+333
-64
lines changed

16 files changed

+333
-64
lines changed

src/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopQueries.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
setTopQueriesFilters,
99
topQueriesApi,
1010
} from '../../../../../store/reducers/executeTopQueries/executeTopQueries';
11-
import {changeUserInput} from '../../../../../store/reducers/query/query';
11+
import {changeUserInput, setIsDirty} from '../../../../../store/reducers/query/query';
1212
import {
1313
TENANT_DIAGNOSTICS_TABS_IDS,
1414
TENANT_PAGE,
@@ -57,6 +57,7 @@ export function TopQueries({tenantName}: TopQueriesProps) {
5757
const {QueryText: input} = row;
5858

5959
dispatch(changeUserInput({input}));
60+
dispatch(setIsDirty(false));
6061

6162
const queryParams = parseQuery(location);
6263

src/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {Search} from '../../../../components/Search';
1212
import {TableWithControlsLayout} from '../../../../components/TableWithControlsLayout/TableWithControlsLayout';
1313
import {parseQuery} from '../../../../routes';
1414
import {setTopQueriesFilters} from '../../../../store/reducers/executeTopQueries/executeTopQueries';
15-
import {changeUserInput} from '../../../../store/reducers/query/query';
15+
import {changeUserInput, setIsDirty} from '../../../../store/reducers/query/query';
1616
import {
1717
TENANT_PAGE,
1818
TENANT_PAGES_IDS,
@@ -72,6 +72,7 @@ export const TopQueries = ({tenantName}: TopQueriesProps) => {
7272
const applyRowClick = React.useCallback(
7373
(input: string) => {
7474
dispatch(changeUserInput({input}));
75+
dispatch(setIsDirty(false));
7576

7677
const queryParams = parseQuery(location);
7778

src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {NavigationTree} from 'ydb-ui-components';
77

88
import {getConnectToDBDialog} from '../../../../components/ConnectToDB/ConnectToDBDialog';
99
import {useCreateDirectoryFeatureAvailable} from '../../../../store/reducers/capabilities/hooks';
10-
import {selectUserInput} from '../../../../store/reducers/query/query';
10+
import {selectIsDirty, selectUserInput} from '../../../../store/reducers/query/query';
1111
import {schemaApi} from '../../../../store/reducers/schema/schema';
1212
import {tableSchemaDataApi} from '../../../../store/reducers/tableSchemaData';
1313
import type {EPathType, TEvDescribeSchemeResult} from '../../../../types/api/schema';
@@ -42,6 +42,7 @@ export function SchemaTree(props: SchemaTreeProps) {
4242
const {rootPath, rootName, rootType, currentPath, onActivePathUpdate} = props;
4343
const dispatch = useTypedDispatch();
4444
const input = useTypedSelector(selectUserInput);
45+
const isDirty = useTypedSelector(selectIsDirty);
4546
const [
4647
getTableSchemaDataQuery,
4748
{currentData: actionsSchemaData, isFetching: isActionsDataFetching},
@@ -132,7 +133,7 @@ export function SchemaTree(props: SchemaTreeProps) {
132133
showCreateDirectoryDialog: createDirectoryFeatureAvailable
133134
? handleOpenCreateDirectoryDialog
134135
: undefined,
135-
getConfirmation: input ? getConfirmation : undefined,
136+
getConfirmation: input && isDirty ? getConfirmation : undefined,
136137
getConnectToDBDialog,
137138
schemaData: actionsSchemaData,
138139
isSchemaDataLoading: isActionsDataFetching,

src/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {TruncatedQuery} from '../../../../components/TruncatedQuery/TruncatedQue
77
import {
88
selectQueriesHistory,
99
selectQueriesHistoryFilter,
10+
setIsDirty,
1011
setQueryHistoryFilter,
1112
} from '../../../../store/reducers/query/query';
1213
import type {QueryInHistory} from '../../../../store/reducers/query/types';
@@ -39,6 +40,7 @@ function QueriesHistory({changeUserInput}: QueriesHistoryProps) {
3940

4041
const applyQueryClick = (query: QueryInHistory) => {
4142
changeUserInput({input: query.queryText});
43+
dispatch(setIsDirty(false));
4244
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
4345
};
4446

src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
selectQueriesHistoryCurrentIndex,
1717
selectResult,
1818
selectTenantPath,
19+
setIsDirty,
1920
setTenantPath,
2021
} from '../../../../store/reducers/query/query';
2122
import type {QueryResult} from '../../../../store/reducers/query/types';
@@ -174,6 +175,7 @@ export default function QueryEditor(props: QueryEditorProps) {
174175
if (text !== historyQueries[historyCurrentIndex]?.queryText) {
175176
dispatch(saveQueryToHistory({queryText: text, queryId}));
176177
}
178+
dispatch(setIsDirty(false));
177179
}
178180
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
179181
});

src/containers/Tenant/Query/QueryEditor/YqlEditor.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
goToPreviousQuery,
1212
selectQueriesHistory,
1313
selectUserInput,
14+
setIsDirty,
1415
} from '../../../../store/reducers/query/query';
1516
import type {QueryAction} from '../../../../types/store/query';
1617
import {ENABLE_CODE_ASSISTANT, LAST_USED_QUERY_ACTION_KEY} from '../../../../utils/constants';
@@ -186,6 +187,7 @@ export function YqlEditor({
186187
const onChange = (newValue: string) => {
187188
updateErrorsHighlighting();
188189
changeUserInput({input: newValue});
190+
dispatch(setIsDirty(true));
189191
};
190192
return (
191193
<MonacoEditor

src/containers/Tenant/Query/SaveQuery/SaveQuery.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import NiceModal from '@ebay/nice-modal-react';
44
import type {ButtonProps} from '@gravity-ui/uikit';
55
import {Button, Dialog, DropdownMenu, TextInput} from '@gravity-ui/uikit';
66

7+
import {setIsDirty} from '../../../../store/reducers/query/query';
78
import {
89
clearQueryNameToEdit,
910
saveQuery,
@@ -55,6 +56,7 @@ export function SaveQuery({buttonProps = {}}: SaveQueryProps) {
5556

5657
const onEditQueryClick = () => {
5758
dispatch(saveQuery(queryNameToEdit));
59+
dispatch(setIsDirty(false));
5860
dispatch(clearQueryNameToEdit());
5961
};
6062

@@ -130,6 +132,7 @@ function SaveQueryDialog({onSuccess, onCancel, onClose, open}: SaveQueryDialogPr
130132

131133
const onSaveClick = () => {
132134
dispatch(saveQuery(queryName));
135+
dispatch(setIsDirty(false));
133136
onCloseDialog();
134137
onSuccess?.();
135138
};

src/containers/Tenant/Query/SavedQueries/SavedQueries.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/Re
99
import {Search} from '../../../../components/Search';
1010
import {TableWithControlsLayout} from '../../../../components/TableWithControlsLayout/TableWithControlsLayout';
1111
import {TruncatedQuery} from '../../../../components/TruncatedQuery/TruncatedQuery';
12+
import {setIsDirty} from '../../../../store/reducers/query/query';
1213
import {
1314
deleteSavedQuery,
1415
selectSavedQueriesFilter,
@@ -92,6 +93,7 @@ export const SavedQueries = ({changeUserInput}: SavedQueriesProps) => {
9293
const applyQueryClick = React.useCallback(
9394
({queryText, queryName}: {queryText: string; queryName: string}) => {
9495
changeUserInput({input: queryText});
96+
dispatch(setIsDirty(false));
9597
dispatch(setQueryNameToEdit(queryName));
9698
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
9799
},

src/store/reducers/query/query.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const sliceLimit = queriesHistoryInitial.length - MAXIMUM_QUERIES_IN_HISTORY;
3131

3232
const initialState: QueryState = {
3333
input: '',
34+
isDirty: false,
3435
history: {
3536
queries: queriesHistoryInitial
3637
.slice(sliceLimit < 0 ? 0 : sliceLimit)
@@ -50,6 +51,9 @@ const slice = createSlice({
5051
changeUserInput: (state, action: PayloadAction<{input: string}>) => {
5152
state.input = action.payload.input;
5253
},
54+
setIsDirty: (state, action: PayloadAction<boolean>) => {
55+
state.isDirty = action.payload;
56+
},
5357
setQueryResult: (state, action: PayloadAction<QueryResult | undefined>) => {
5458
state.result = action.payload;
5559
},
@@ -145,6 +149,7 @@ const slice = createSlice({
145149
: items;
146150
},
147151
selectUserInput: (state) => state.input,
152+
selectIsDirty: (state) => state.isDirty,
148153
selectQueriesHistoryCurrentIndex: (state) => state.history?.currentIndex,
149154
},
150155
});
@@ -162,6 +167,7 @@ export const {
162167
addStreamingChunks,
163168
setStreamQueryResponse,
164169
setStreamSession,
170+
setIsDirty,
165171
} = slice.actions;
166172

167173
export const {
@@ -172,6 +178,7 @@ export const {
172178
selectResult,
173179
selectUserInput,
174180
selectQueryDuration,
181+
selectIsDirty,
175182
} = slice.selectors;
176183

177184
interface SendQueryParams extends QueryRequestParams {

src/store/reducers/query/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export interface QueryResult {
6161
export interface QueryState {
6262
input: string;
6363
result?: QueryResult;
64+
isDirty?: boolean;
6465
history: {
6566
queries: QueryInHistory[];
6667
currentIndex: number;

0 commit comments

Comments
 (0)