Skip to content

Commit deed421

Browse files
fix(SavedQueries): move queries manipulations to hook (#3102)
1 parent 85a3075 commit deed421

File tree

5 files changed

+77
-70
lines changed

5 files changed

+77
-70
lines changed

src/containers/Tenant/Query/QueryEditor/helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function useCodeAssistHelpers() {
4646
const [ignoreSuggestion] = codeAssistApi.useIgnoreSuggestionMutation();
4747
const [sendUserQueriesData] = codeAssistApi.useSendUserQueriesDataMutation();
4848
const historyQueries = useTypedSelector(selectQueriesHistory);
49-
const savedQueries = useSavedQueries();
49+
const {savedQueries} = useSavedQueries();
5050

5151
const getCodeAssistSuggestions = React.useCallback(
5252
async (promptFiles: PromptFile[]) => sendCodeAssistPrompt(promptFiles).unwrap(),
@@ -74,7 +74,7 @@ export function useCodeAssistHelpers() {
7474
name: `query${index}.yql`,
7575
text: query.queryText,
7676
})),
77-
...savedQueries.map((query) => ({
77+
...(savedQueries ?? []).map((query) => ({
7878
name: query.name,
7979
text: query.body,
8080
})),

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import {Button, Dialog, DropdownMenu, TextInput} from '@gravity-ui/uikit';
77
import {setIsDirty} from '../../../../store/reducers/query/query';
88
import {
99
clearQueryNameToEdit,
10-
saveQuery,
1110
selectQueryName,
1211
setQueryAction,
1312
} from '../../../../store/reducers/queryActions/queryActions';
13+
import type {SavedQuery} from '../../../../types/store/query';
1414
import {cn} from '../../../../utils/cn';
1515
import {useTypedDispatch, useTypedSelector} from '../../../../utils/hooks';
1616
import {useSavedQueries} from '../utils/useSavedQueries';
@@ -27,10 +27,16 @@ interface SaveQueryProps {
2727

2828
function useSaveQueryHandler(dialogProps?: SaveQueryDialogCommonProps) {
2929
const dispatch = useTypedDispatch();
30+
const {savedQueries, saveQuery} = useSavedQueries();
31+
3032
const onSaveQueryClick = React.useCallback(() => {
31-
NiceModal.show(SAVE_QUERY_DIALOG, dialogProps);
33+
NiceModal.show(SAVE_QUERY_DIALOG, {
34+
...dialogProps,
35+
savedQueries,
36+
onSaveQuery: saveQuery,
37+
});
3238
dispatch(clearQueryNameToEdit());
33-
}, [dispatch, dialogProps]);
39+
}, [dispatch, dialogProps, savedQueries, saveQuery]);
3440

3541
return onSaveQueryClick;
3642
}
@@ -54,8 +60,10 @@ export function SaveQuery({buttonProps = {}}: SaveQueryProps) {
5460
const queryNameToEdit = useTypedSelector(selectQueryName);
5561
const onSaveQueryClick = useSaveQueryHandler();
5662

63+
const {saveQuery} = useSavedQueries();
64+
5765
const onEditQueryClick = () => {
58-
dispatch(saveQuery(queryNameToEdit));
66+
saveQuery(queryNameToEdit);
5967
dispatch(setIsDirty(false));
6068
dispatch(clearQueryNameToEdit());
6169
};
@@ -95,10 +103,18 @@ interface SaveQueryDialogCommonProps {
95103

96104
interface SaveQueryDialogProps extends SaveQueryDialogCommonProps {
97105
open: boolean;
106+
savedQueries?: SavedQuery[];
107+
onSaveQuery: (name: string | null) => void;
98108
}
99109

100-
function SaveQueryDialog({onSuccess, onCancel, onClose, open}: SaveQueryDialogProps) {
101-
const savedQueries = useSavedQueries();
110+
function SaveQueryDialog({
111+
onSuccess,
112+
onCancel,
113+
onClose,
114+
open,
115+
savedQueries,
116+
onSaveQuery,
117+
}: SaveQueryDialogProps) {
102118
const dispatch = useTypedDispatch();
103119
const [queryName, setQueryName] = React.useState('');
104120
const [validationError, setValidationError] = React.useState<string>();
@@ -107,7 +123,7 @@ function SaveQueryDialog({onSuccess, onCancel, onClose, open}: SaveQueryDialogPr
107123
if (!value) {
108124
return i18n('error.name-not-empty');
109125
}
110-
if (savedQueries.some((q) => q.name.toLowerCase() === value.trim().toLowerCase())) {
126+
if (savedQueries?.some((q) => q.name.toLowerCase() === value.trim().toLowerCase())) {
111127
return i18n('error.name-exists');
112128
}
113129
return undefined;
@@ -131,7 +147,7 @@ function SaveQueryDialog({onSuccess, onCancel, onClose, open}: SaveQueryDialogPr
131147
};
132148

133149
const onSaveClick = () => {
134-
dispatch(saveQuery(queryName));
150+
onSaveQuery(queryName);
135151
dispatch(setIsDirty(false));
136152
onCloseDialog();
137153
onSuccess?.();

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {TableWithControlsLayout} from '../../../../components/TableWithControlsL
1111
import {TruncatedQuery} from '../../../../components/TruncatedQuery/TruncatedQuery';
1212
import {setIsDirty} from '../../../../store/reducers/query/query';
1313
import {
14-
deleteSavedQuery,
1514
selectSavedQueriesFilter,
1615
setQueryNameToEdit,
1716
setSavedQueriesFilter,
@@ -24,7 +23,7 @@ import {useTypedDispatch, useTypedSelector} from '../../../../utils/hooks';
2423
import {useChangeInputWithConfirmation} from '../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation';
2524
import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants';
2625
import i18n from '../i18n';
27-
import {useFilteredSavedQueries} from '../utils/useSavedQueries';
26+
import {useSavedQueries} from '../utils/useSavedQueries';
2827

2928
import './SavedQueries.scss';
3029

@@ -68,7 +67,7 @@ interface SavedQueriesProps {
6867
}
6968

7069
export const SavedQueries = ({changeUserInput}: SavedQueriesProps) => {
71-
const savedQueries = useFilteredSavedQueries();
70+
const {filteredSavedQueries, deleteSavedQuery} = useSavedQueries();
7271
const dispatch = useTypedDispatch();
7372
const filter = useTypedSelector(selectSavedQueriesFilter);
7473

@@ -86,7 +85,7 @@ export const SavedQueries = ({changeUserInput}: SavedQueriesProps) => {
8685

8786
const onConfirmDeleteClick = () => {
8887
closeDeleteDialog();
89-
dispatch(deleteSavedQuery(queryNameToDelete));
88+
deleteSavedQuery(queryNameToDelete);
9089
setQueryNameToDelete('');
9190
};
9291

@@ -158,7 +157,7 @@ export const SavedQueries = ({changeUserInput}: SavedQueriesProps) => {
158157
<ResizeableDataTable
159158
columnsWidthLSKey={SAVED_QUERIES_COLUMNS_WIDTH_LS_KEY}
160159
columns={columns}
161-
data={savedQueries}
160+
data={filteredSavedQueries}
162161
settings={QUERY_TABLE_SETTINGS}
163162
emptyDataMessage={i18n(filter ? 'history.empty-search' : 'saved.empty')}
164163
rowClassName={() => b('row')}

src/containers/Tenant/Query/utils/useSavedQueries.tsx

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,58 @@ import type {SavedQuery} from '../../../../types/store/query';
66
import {useSetting, useTypedSelector} from '../../../../utils/hooks';
77

88
export function useSavedQueries() {
9-
const [savedQueries] = useSetting<SavedQuery[]>(SETTING_KEYS.SAVED_QUERIES, []);
9+
const [savedQueries, saveQueries] = useSetting<SavedQuery[]>(SETTING_KEYS.SAVED_QUERIES);
1010

11-
return savedQueries;
12-
}
13-
14-
export function useFilteredSavedQueries() {
15-
const savedQueries = useSavedQueries();
1611
const filter = useTypedSelector(selectSavedQueriesFilter).trim().toLowerCase();
12+
const currentInput = useTypedSelector((state) => state.query.input);
1713

1814
const filteredSavedQueries = React.useMemo(() => {
19-
if (filter.length === 0) {
20-
return savedQueries;
15+
const queries = savedQueries ?? [];
16+
17+
if (filter) {
18+
return queries.filter((item) => item.body.toLowerCase().includes(filter));
2119
}
22-
return savedQueries.filter((item) => item.body.toLowerCase().includes(filter));
20+
return queries;
2321
}, [savedQueries, filter]);
2422

25-
return filteredSavedQueries;
23+
const deleteSavedQuery = React.useCallback(
24+
(queryName: string) => {
25+
const queries = savedQueries ?? [];
26+
const nextSavedQueries = queries.filter((el) => !findQueryByName(el, queryName));
27+
28+
saveQueries(nextSavedQueries);
29+
},
30+
[savedQueries, saveQueries],
31+
);
32+
33+
const saveQuery = React.useCallback(
34+
(queryName: string | null) => {
35+
if (!queryName) {
36+
return;
37+
}
38+
39+
const currentQueries = savedQueries ?? [];
40+
const nextSavedQueries = [...currentQueries];
41+
42+
const queryIndex = currentQueries.findIndex((el) => findQueryByName(el, queryName));
43+
44+
if (queryIndex >= 0) {
45+
nextSavedQueries[queryIndex] = {
46+
...currentQueries[queryIndex],
47+
body: currentInput,
48+
};
49+
} else {
50+
nextSavedQueries.push({name: queryName, body: currentInput});
51+
}
52+
53+
saveQueries(nextSavedQueries);
54+
},
55+
[savedQueries, saveQueries, currentInput],
56+
);
57+
58+
return {savedQueries, filteredSavedQueries, deleteSavedQuery, saveQuery};
59+
}
60+
61+
function findQueryByName(query: SavedQuery, name: string) {
62+
return query.name.toLowerCase() === name.toLowerCase();
2663
}
Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import type {PayloadAction} from '@reduxjs/toolkit';
22
import {createSlice} from '@reduxjs/toolkit';
33

4-
import {settingsManager} from '../../../services/settings';
5-
import type {SavedQuery} from '../../../types/store/query';
6-
import type {AppDispatch, GetState} from '../../defaultStore';
7-
import {SETTING_KEYS} from '../settings/constants';
8-
import {getSettingValue, setSettingValue} from '../settings/settings';
9-
104
import type {QueryActions, QueryActionsState} from './types';
115

126
const initialState: QueryActionsState = {
@@ -43,42 +37,3 @@ export default slice.reducer;
4337
export const {setQueryNameToEdit, clearQueryNameToEdit, setQueryAction, setSavedQueriesFilter} =
4438
slice.actions;
4539
export const {selectQueryName, selectQueryAction, selectSavedQueriesFilter} = slice.selectors;
46-
47-
export function deleteSavedQuery(queryName: string) {
48-
return function deleteSavedQueryThunk(dispatch: AppDispatch, getState: GetState) {
49-
const state = getState();
50-
const savedQueries =
51-
(getSettingValue(state, SETTING_KEYS.SAVED_QUERIES) as SavedQuery[]) ?? [];
52-
const newSavedQueries = savedQueries.filter(
53-
(el) => el.name.toLowerCase() !== queryName.toLowerCase(),
54-
);
55-
dispatch(setSettingValue(SETTING_KEYS.SAVED_QUERIES, newSavedQueries));
56-
settingsManager.setUserSettingsValue(SETTING_KEYS.SAVED_QUERIES, newSavedQueries);
57-
};
58-
}
59-
60-
export function saveQuery(queryName: string | null) {
61-
return function saveQueryThunk(dispatch: AppDispatch, getState: GetState) {
62-
const state = getState();
63-
const savedQueries =
64-
(getSettingValue(state, SETTING_KEYS.SAVED_QUERIES) as SavedQuery[]) ?? [];
65-
const queryBody = state.query.input;
66-
if (queryName === null) {
67-
return;
68-
}
69-
const nextSavedQueries = [...savedQueries];
70-
71-
const query = nextSavedQueries.find(
72-
(el) => el.name.toLowerCase() === queryName.toLowerCase(),
73-
);
74-
75-
if (query) {
76-
query.body = queryBody;
77-
} else {
78-
nextSavedQueries.push({name: queryName, body: queryBody});
79-
}
80-
81-
dispatch(setSettingValue(SETTING_KEYS.SAVED_QUERIES, nextSavedQueries));
82-
settingsManager.setUserSettingsValue(SETTING_KEYS.SAVED_QUERIES, nextSavedQueries);
83-
};
84-
}

0 commit comments

Comments
 (0)