Enhancement for Save View PRD. (#3471)

* refactor: search in dropdown

* refactor: name of the view to i18

* refactor: make the use of useForm from antd

* refactor: moved QuerySearchParamNames into save view module

* refactor: reset to query build when click on explorer link

* refactor: reverted resetQuery in querybuilder

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
Rajat Dabade 2023-09-08 20:36:21 +05:30 committed by GitHub
parent f17608fa10
commit 004f10e73b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 164 additions and 128 deletions

View File

@ -0,0 +1,3 @@
{
"name_of_the_view": "Name of the view"
}

View File

@ -0,0 +1,3 @@
{
"name_of_the_view": "Name of the view"
}

View File

@ -1,6 +1,5 @@
import { import {
DeleteOutlined, DeleteOutlined,
DownOutlined,
MoreOutlined, MoreOutlined,
SaveOutlined, SaveOutlined,
ShareAltOutlined, ShareAltOutlined,
@ -13,13 +12,13 @@ import {
MenuProps, MenuProps,
Popover, Popover,
Row, Row,
Select,
Space, Space,
Typography, Typography,
} from 'antd'; } from 'antd';
import axios from 'axios'; import axios from 'axios';
import TextToolTip from 'components/TextToolTip'; import TextToolTip from 'components/TextToolTip';
import { SOMETHING_WENT_WRONG } from 'constants/api'; import { SOMETHING_WENT_WRONG } from 'constants/api';
import { querySearchParams } from 'constants/queryBuilderQueryNames';
import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam'; import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useDeleteView } from 'hooks/saveViews/useDeleteView'; import { useDeleteView } from 'hooks/saveViews/useDeleteView';
@ -28,10 +27,14 @@ import { useUpdateView } from 'hooks/saveViews/useUpdateView';
import useErrorNotification from 'hooks/useErrorNotification'; import useErrorNotification from 'hooks/useErrorNotification';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery'; import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useEffect, useState } from 'react';
import { useCopyToClipboard } from 'react-use'; import { useCopyToClipboard } from 'react-use';
import { ExploreHeaderToolTip, SaveButtonText } from './constants'; import {
ExploreHeaderToolTip,
querySearchParams,
SaveButtonText,
} from './constants';
import MenuItemGenerator from './MenuItemGenerator'; import MenuItemGenerator from './MenuItemGenerator';
import SaveViewWithName from './SaveViewWithName'; import SaveViewWithName from './SaveViewWithName';
import { import {
@ -63,6 +66,7 @@ function ExplorerCard({
currentQuery, currentQuery,
panelType, panelType,
redirectWithQueryBuilderData, redirectWithQueryBuilderData,
updateAllQueriesOperators,
} = useQueryBuilder(); } = useQueryBuilder();
const { const {
@ -75,11 +79,7 @@ function ExplorerCard({
useErrorNotification(error); useErrorNotification(error);
const handlePopOverClose = (): void => { const handleOpenChange = (newOpen = false): void => {
setIsOpen(false);
};
const handleOpenChange = (newOpen: boolean): void => {
setIsOpen(newOpen); setIsOpen(newOpen);
}; };
@ -104,7 +104,7 @@ function ExplorerCard({
}); });
}; };
const onDeleteHandler = useCallback(() => { const onDeleteHandler = (): void =>
deleteViewHandler({ deleteViewHandler({
deleteViewAsync, deleteViewAsync,
notifications, notifications,
@ -113,15 +113,9 @@ function ExplorerCard({
refetchAllView, refetchAllView,
viewId: viewKey, viewId: viewKey,
viewKey, viewKey,
updateAllQueriesOperators,
sourcePage: sourcepage,
}); });
}, [
deleteViewAsync,
notifications,
panelType,
redirectWithQueryBuilderData,
refetchAllView,
viewKey,
]);
const onUpdateQueryHandler = (): void => { const onUpdateQueryHandler = (): void => {
updateViewAsync( updateViewAsync(
@ -165,38 +159,16 @@ function ExplorerCard({
panelType, panelType,
]); ]);
const menu = useMemo( const moreOptionMenu: MenuProps = {
(): MenuProps => ({ items: [
items: viewsData?.data?.data?.map((view) => ({ {
key: view.uuid, key: 'delete',
label: ( label: <Typography.Text strong>Delete</Typography.Text>,
<MenuItemGenerator onClick: onDeleteHandler,
viewName={view.name} icon: <DeleteOutlined />,
viewKey={viewKey} },
createdBy={view.createdBy} ],
uuid={view.uuid} };
refetchAllView={refetchAllView}
viewData={viewsData.data.data}
/>
),
})),
}),
[refetchAllView, viewKey, viewsData?.data?.data],
);
const moreOptionMenu = useMemo(
(): MenuProps => ({
items: [
{
key: 'delete',
label: <Typography.Text strong>Delete</Typography.Text>,
onClick: onDeleteHandler,
icon: <DeleteOutlined />,
},
],
}),
[onDeleteHandler],
);
const saveButtonType = isQueryUpdated ? 'default' : 'primary'; const saveButtonType = isQueryUpdated ? 'default' : 'primary';
const saveButtonIcon = isQueryUpdated ? null : <SaveOutlined />; const saveButtonIcon = isQueryUpdated ? null : <SaveOutlined />;
@ -215,20 +187,32 @@ function ExplorerCard({
/> />
</Space> </Space>
</Col> </Col>
<OffSetCol span={10} offset={8}> <OffSetCol span={18}>
<Space size="large"> <Space size="large">
{viewsData?.data.data && viewsData?.data.data.length && ( {viewsData?.data.data && viewsData?.data.data.length && (
<Space> <Space>
{/* <Typography.Text>Saved Views</Typography.Text> */} <Select
<Dropdown.Button
menu={menu}
loading={isLoading || isRefetching} loading={isLoading || isRefetching}
icon={<DownOutlined />} showSearch
trigger={['click']} placeholder="Select a view"
overlayStyle={DropDownOverlay} dropdownStyle={DropDownOverlay}
dropdownMatchSelectWidth={false}
value={null}
> >
Select View {viewsData?.data.data.map((view) => (
</Dropdown.Button> <Select.Option key={view.uuid} value={view.name}>
<MenuItemGenerator
viewName={view.name}
viewKey={viewKey}
createdBy={view.createdBy}
uuid={view.uuid}
refetchAllView={refetchAllView}
viewData={viewsData.data.data}
sourcePage={sourcepage}
/>
</Select.Option>
))}
</Select>
</Space> </Space>
)} )}
{isQueryUpdated && ( {isQueryUpdated && (
@ -246,7 +230,7 @@ function ExplorerCard({
content={ content={
<SaveViewWithName <SaveViewWithName
sourcePage={sourcepage} sourcePage={sourcepage}
handlePopOverClose={handlePopOverClose} handlePopOverClose={handleOpenChange}
refetchAllView={refetchAllView} refetchAllView={refetchAllView}
/> />
} }

View File

@ -17,9 +17,15 @@ function MenuItemGenerator({
uuid, uuid,
viewData, viewData,
refetchAllView, refetchAllView,
sourcePage,
}: MenuItemLabelGeneratorProps): JSX.Element { }: MenuItemLabelGeneratorProps): JSX.Element {
const { panelType, redirectWithQueryBuilderData } = useQueryBuilder(); const {
panelType,
redirectWithQueryBuilderData,
updateAllQueriesOperators,
} = useQueryBuilder();
const { handleExplorerTabChange } = useHandleExplorerTabChange(); const { handleExplorerTabChange } = useHandleExplorerTabChange();
const { notifications } = useNotifications(); const { notifications } = useNotifications();
const { mutateAsync: deleteViewAsync } = useDeleteView(uuid); const { mutateAsync: deleteViewAsync } = useDeleteView(uuid);
@ -34,6 +40,8 @@ function MenuItemGenerator({
refetchAllView, refetchAllView,
viewId: uuid, viewId: uuid,
viewKey, viewKey,
updateAllQueriesOperators,
sourcePage,
}); });
}; };

View File

@ -1,13 +1,13 @@
import { Card, Input, Typography } from 'antd'; import { Card, Form, Input, Typography } from 'antd';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useSaveView } from 'hooks/saveViews/useSaveView'; import { useSaveView } from 'hooks/saveViews/useSaveView';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery'; import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
import { ChangeEvent, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next';
import { SaveButton } from './styles'; import { SaveButton } from './styles';
import { SaveViewWithNameProps } from './types'; import { SaveViewFormProps, SaveViewWithNameProps } from './types';
import { saveViewHandler } from './utils'; import { saveViewHandler } from './utils';
function SaveViewWithName({ function SaveViewWithName({
@ -15,7 +15,8 @@ function SaveViewWithName({
handlePopOverClose, handlePopOverClose,
refetchAllView, refetchAllView,
}: SaveViewWithNameProps): JSX.Element { }: SaveViewWithNameProps): JSX.Element {
const [name, setName] = useState(''); const [form] = Form.useForm<SaveViewFormProps>();
const { t } = useTranslation(['explorer']);
const { const {
currentQuery, currentQuery,
panelType, panelType,
@ -25,19 +26,12 @@ function SaveViewWithName({
const compositeQuery = mapCompositeQueryFromQuery(currentQuery, panelType); const compositeQuery = mapCompositeQueryFromQuery(currentQuery, panelType);
const { isLoading, mutateAsync: saveViewAsync } = useSaveView({ const { isLoading, mutateAsync: saveViewAsync } = useSaveView({
viewName: name, viewName: form.getFieldValue('viewName'),
compositeQuery, compositeQuery,
sourcePage, sourcePage,
extraData: '', extraData: '',
}); });
const onChangeHandler = useCallback(
(e: ChangeEvent<HTMLInputElement>): void => {
setName(e.target.value);
},
[],
);
const onSaveHandler = (): void => { const onSaveHandler = (): void => {
saveViewHandler({ saveViewHandler({
compositeQuery, compositeQuery,
@ -49,18 +43,32 @@ function SaveViewWithName({
refetchAllView, refetchAllView,
saveViewAsync, saveViewAsync,
sourcePage, sourcePage,
viewName: name, viewName: form.getFieldValue('viewName'),
setName, form,
}); });
}; };
return ( return (
<Card> <Card>
<Typography>Name of the View</Typography> <Typography>{t('name_of_the_view')}</Typography>
<Input placeholder="Enter Name" onChange={onChangeHandler} /> <Form form={form} onFinish={onSaveHandler}>
<SaveButton onClick={onSaveHandler} type="primary" loading={isLoading}> <Form.Item
Save name={['viewName']}
</SaveButton> required
requiredMark
rules={[
{
required: true,
message: 'Please enter view name',
},
]}
>
<Input placeholder="Enter Name" />
</Form.Item>
<SaveButton htmlType="submit" type="primary" loading={isLoading}>
Save
</SaveButton>
</Form>
</Card> </Card>
); );
} }

View File

@ -8,3 +8,13 @@ export const SaveButtonText = {
SAVE_AS_NEW_VIEW: 'Save as new view', SAVE_AS_NEW_VIEW: 'Save as new view',
SAVE_VIEW: 'Save view', SAVE_VIEW: 'Save view',
}; };
export type QuerySearchParamNames = 'viewName' | 'viewKey';
export const querySearchParams: Record<
QuerySearchParamNames,
QuerySearchParamNames
> = {
viewName: 'viewName',
viewKey: 'viewKey',
};

View File

@ -62,15 +62,12 @@ describe('ExplorerCard', () => {
const screen = render( const screen = render(
<ExplorerCard sourcepage={DataSource.TRACES}>Mock Children</ExplorerCard>, <ExplorerCard sourcepage={DataSource.TRACES}>Mock Children</ExplorerCard>,
); );
const selectButton = screen.getByText('Select View'); const selectPlaceholder = screen.getByText('Select a view');
fireEvent.click(selectButton); fireEvent.mouseDown(selectPlaceholder);
const viewNameText = await screen.getAllByText('View 1');
const spanElement = screen.getByRole('img', { viewNameText.forEach((element) => {
name: 'down', expect(element).toBeInTheDocument();
}); });
fireEvent.click(spanElement);
const viewNameText = await screen.findByText('View 2');
expect(viewNameText).toBeInTheDocument();
}); });
}); });

View File

@ -1,6 +1,7 @@
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import MockQueryClientProvider from 'providers/test/MockQueryClientProvider'; import MockQueryClientProvider from 'providers/test/MockQueryClientProvider';
import { DataSource } from 'types/common/queryBuilder';
import { viewMockData } from '../__mock__/viewData'; import { viewMockData } from '../__mock__/viewData';
import MenuItemGenerator from '../MenuItemGenerator'; import MenuItemGenerator from '../MenuItemGenerator';
@ -12,6 +13,12 @@ jest.mock('react-router-dom', () => ({
}), }),
})); }));
jest.mock('antd/es/form/Form', () => ({
useForm: jest.fn().mockReturnValue({
onFinish: jest.fn(),
}),
}));
describe('MenuItemGenerator', () => { describe('MenuItemGenerator', () => {
it('should render MenuItemGenerator component', () => { it('should render MenuItemGenerator component', () => {
const screen = render( const screen = render(
@ -23,6 +30,7 @@ describe('MenuItemGenerator', () => {
uuid={viewMockData[0].uuid} uuid={viewMockData[0].uuid}
refetchAllView={jest.fn()} refetchAllView={jest.fn()}
viewData={viewMockData} viewData={viewMockData}
sourcePage={DataSource.TRACES}
/> />
</MockQueryClientProvider>, </MockQueryClientProvider>,
); );
@ -40,6 +48,7 @@ describe('MenuItemGenerator', () => {
uuid={viewMockData[0].uuid} uuid={viewMockData[0].uuid}
refetchAllView={jest.fn()} refetchAllView={jest.fn()}
viewData={viewMockData} viewData={viewMockData}
sourcePage={DataSource.TRACES}
/> />
</MockQueryClientProvider>, </MockQueryClientProvider>,
); );

View File

@ -1,7 +1,7 @@
import { FormInstance } from 'antd';
import { NotificationInstance } from 'antd/es/notification/interface'; import { NotificationInstance } from 'antd/es/notification/interface';
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { SetStateAction } from 'react';
import { UseMutateAsyncFunction } from 'react-query'; import { UseMutateAsyncFunction } from 'react-query';
import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery'; import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery';
import { Query } from 'types/api/queryBuilder/queryBuilderData'; import { Query } from 'types/api/queryBuilder/queryBuilderData';
@ -38,6 +38,10 @@ export interface SaveViewWithNameProps {
refetchAllView: VoidFunction; refetchAllView: VoidFunction;
} }
export interface SaveViewFormProps {
viewName: string;
}
export interface MenuItemLabelGeneratorProps { export interface MenuItemLabelGeneratorProps {
viewName: string; viewName: string;
viewKey: string; viewKey: string;
@ -45,6 +49,7 @@ export interface MenuItemLabelGeneratorProps {
uuid: string; uuid: string;
viewData: ViewProps[]; viewData: ViewProps[];
refetchAllView: VoidFunction; refetchAllView: VoidFunction;
sourcePage: ExplorerCardProps['sourcepage'];
} }
export interface SaveViewHandlerProps { export interface SaveViewHandlerProps {
@ -63,7 +68,7 @@ export interface SaveViewHandlerProps {
>; >;
handlePopOverClose: SaveViewWithNameProps['handlePopOverClose']; handlePopOverClose: SaveViewWithNameProps['handlePopOverClose'];
redirectWithQueryBuilderData: QueryBuilderContextType['redirectWithQueryBuilderData']; redirectWithQueryBuilderData: QueryBuilderContextType['redirectWithQueryBuilderData'];
setName: (value: SetStateAction<string>) => void; form: FormInstance<SaveViewFormProps>;
} }
export interface DeleteViewHandlerProps { export interface DeleteViewHandlerProps {
@ -74,4 +79,6 @@ export interface DeleteViewHandlerProps {
panelType: PANEL_TYPES | null; panelType: PANEL_TYPES | null;
viewKey: string; viewKey: string;
viewId: string; viewId: string;
updateAllQueriesOperators: QueryBuilderContextType['updateAllQueriesOperators'];
sourcePage: ExplorerCardProps['sourcepage'];
} }

View File

@ -1,14 +1,12 @@
import { NotificationInstance } from 'antd/es/notification/interface'; import { NotificationInstance } from 'antd/es/notification/interface';
import axios from 'axios'; import axios from 'axios';
import { SOMETHING_WENT_WRONG } from 'constants/api'; import { SOMETHING_WENT_WRONG } from 'constants/api';
import { initialQueriesMap } from 'constants/queryBuilder'; import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import { import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
queryParamNamesMap,
querySearchParams,
} from 'constants/queryBuilderQueryNames';
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi'; import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
import isEqual from 'lodash-es/isEqual'; import isEqual from 'lodash-es/isEqual';
import { querySearchParams } from './constants';
import { import {
DeleteViewHandlerProps, DeleteViewHandlerProps,
GetViewDetailsUsingViewKey, GetViewDetailsUsingViewKey,
@ -108,7 +106,7 @@ export const saveViewHandler = ({
extraData, extraData,
redirectWithQueryBuilderData, redirectWithQueryBuilderData,
panelType, panelType,
setName, form,
}: SaveViewHandlerProps): void => { }: SaveViewHandlerProps): void => {
saveViewAsync( saveViewAsync(
{ {
@ -134,7 +132,7 @@ export const saveViewHandler = ({
}, },
onSettled: () => { onSettled: () => {
handlePopOverClose(); handlePopOverClose();
setName(''); form.resetFields();
}, },
}, },
); );
@ -148,15 +146,24 @@ export const deleteViewHandler = ({
panelType, panelType,
viewKey, viewKey,
viewId, viewId,
updateAllQueriesOperators,
sourcePage,
}: DeleteViewHandlerProps): void => { }: DeleteViewHandlerProps): void => {
deleteViewAsync(viewKey, { deleteViewAsync(viewKey, {
onSuccess: () => { onSuccess: () => {
if (viewId === viewKey) { if (viewId === viewKey) {
redirectWithQueryBuilderData(initialQueriesMap.traces, { redirectWithQueryBuilderData(
[querySearchParams.viewName]: 'Query Builder', updateAllQueriesOperators(
[queryParamNamesMap.panelTypes]: panelType, initialQueriesMap.traces,
[querySearchParams.viewKey]: '', panelType || PANEL_TYPES.LIST,
}); sourcePage,
),
{
[querySearchParams.viewName]: 'Query Builder',
[queryParamNamesMap.panelTypes]: panelType,
[querySearchParams.viewKey]: '',
},
);
} }
notifications.success({ notifications.success({
message: 'View Deleted Successfully', message: 'View Deleted Successfully',

View File

@ -6,8 +6,6 @@ type QueryParamNames =
| 'selectedFields' | 'selectedFields'
| 'linesPerRow'; | 'linesPerRow';
export type QuerySearchParamNames = 'viewName' | 'viewKey';
export const queryParamNamesMap: Record<QueryParamNames, QueryParamNames> = { export const queryParamNamesMap: Record<QueryParamNames, QueryParamNames> = {
compositeQuery: 'compositeQuery', compositeQuery: 'compositeQuery',
panelTypes: 'panelTypes', panelTypes: 'panelTypes',
@ -16,11 +14,3 @@ export const queryParamNamesMap: Record<QueryParamNames, QueryParamNames> = {
selectedFields: 'selectedFields', selectedFields: 'selectedFields',
linesPerRow: 'linesPerRow', linesPerRow: 'linesPerRow',
}; };
export const querySearchParams: Record<
QuerySearchParamNames,
QuerySearchParamNames
> = {
viewName: 'viewName',
viewKey: 'viewKey',
};

View File

@ -1,4 +1,4 @@
import { QuerySearchParamNames } from 'constants/queryBuilderQueryNames'; import { QuerySearchParamNames } from 'components/ExplorerCard/constants';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import { useMemo } from 'react'; import { useMemo } from 'react';

View File

@ -8,14 +8,21 @@ import { useQueryBuilder } from './useQueryBuilder';
export type UseShareBuilderUrlParams = { defaultValue: Query }; export type UseShareBuilderUrlParams = { defaultValue: Query };
export const useShareBuilderUrl = (defaultQuery: Query): void => { export const useShareBuilderUrl = (defaultQuery: Query): void => {
const { redirectWithQueryBuilderData } = useQueryBuilder(); const { resetQuery, redirectWithQueryBuilderData } = useQueryBuilder();
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
const compositeQuery = useGetCompositeQueryParam(); const compositeQuery = useGetCompositeQueryParam();
useEffect(() => { useEffect(() => {
if (!compositeQuery) { if (!compositeQuery) {
resetQuery(defaultQuery);
redirectWithQueryBuilderData(defaultQuery); redirectWithQueryBuilderData(defaultQuery);
} }
}, [defaultQuery, urlQuery, compositeQuery, redirectWithQueryBuilderData]); }, [
defaultQuery,
urlQuery,
redirectWithQueryBuilderData,
compositeQuery,
resetQuery,
]);
}; };

View File

@ -16,11 +16,5 @@ export const useSaveView = ({
> => > =>
useMutation({ useMutation({
mutationKey: [viewName, sourcePage, compositeQuery, extraData], mutationKey: [viewName, sourcePage, compositeQuery, extraData],
mutationFn: () => mutationFn: saveView,
saveView({
compositeQuery,
sourcePage,
viewName,
extraData,
}),
}); });

View File

@ -1,8 +1,6 @@
import { querySearchParams } from 'components/ExplorerCard/constants';
import { initialAutocompleteData, PANEL_TYPES } from 'constants/queryBuilder'; import { initialAutocompleteData, PANEL_TYPES } from 'constants/queryBuilder';
import { import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
queryParamNamesMap,
querySearchParams,
} from 'constants/queryBuilderQueryNames';
import { SIGNOZ_VALUE } from 'container/QueryBuilder/filters/OrderByFilter/constants'; import { SIGNOZ_VALUE } from 'container/QueryBuilder/filters/OrderByFilter/constants';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { Query } from 'types/api/queryBuilder/queryBuilderData'; import { Query } from 'types/api/queryBuilder/queryBuilderData';
@ -25,8 +23,7 @@ export const useHandleExplorerTabChange = (): {
updateQueriesData, updateQueriesData,
} = useQueryBuilder(); } = useQueryBuilder();
const viewName = const viewName = useGetSearchQueryParam(querySearchParams.viewName) || '';
useGetSearchQueryParam(querySearchParams.viewName) || 'Query Builder';
const viewKey = useGetSearchQueryParam(querySearchParams.viewKey) || ''; const viewKey = useGetSearchQueryParam(querySearchParams.viewKey) || '';

View File

@ -68,6 +68,7 @@ export const QueryBuilderContext = createContext<QueryBuilderContextType>({
addNewQueryItem: () => {}, addNewQueryItem: () => {},
redirectWithQueryBuilderData: () => {}, redirectWithQueryBuilderData: () => {},
handleRunQuery: () => {}, handleRunQuery: () => {},
resetQuery: () => {},
updateAllQueriesOperators: () => initialQueriesMap.metrics, updateAllQueriesOperators: () => initialQueriesMap.metrics,
updateQueriesData: () => initialQueriesMap.metrics, updateQueriesData: () => initialQueriesMap.metrics,
initQueryBuilderData: () => {}, initQueryBuilderData: () => {},
@ -550,6 +551,14 @@ export function QueryBuilderProvider({
stagedQuery, stagedQuery,
]); ]);
const resetQuery = (newCurrentQuery?: QueryState): void => {
setStagedQuery(null);
if (newCurrentQuery) {
setCurrentQuery(newCurrentQuery);
}
};
useEffect(() => { useEffect(() => {
if (stagedQuery && location.pathname !== currentPathnameRef.current) { if (stagedQuery && location.pathname !== currentPathnameRef.current) {
currentPathnameRef.current = location.pathname; currentPathnameRef.current = location.pathname;
@ -599,6 +608,7 @@ export function QueryBuilderProvider({
addNewQueryItem, addNewQueryItem,
redirectWithQueryBuilderData, redirectWithQueryBuilderData,
handleRunQuery, handleRunQuery,
resetQuery,
updateAllQueriesOperators, updateAllQueriesOperators,
updateQueriesData, updateQueriesData,
initQueryBuilderData, initQueryBuilderData,

View File

@ -6,6 +6,7 @@ import {
IClickHouseQuery, IClickHouseQuery,
IPromQLQuery, IPromQLQuery,
Query, Query,
QueryState,
} from 'types/api/queryBuilder/queryBuilderData'; } from 'types/api/queryBuilder/queryBuilderData';
import { EQueryType } from './dashboard'; import { EQueryType } from './dashboard';
@ -187,6 +188,7 @@ export type QueryBuilderContextType = {
searchParams?: Record<string, unknown>, searchParams?: Record<string, unknown>,
) => void; ) => void;
handleRunQuery: () => void; handleRunQuery: () => void;
resetQuery: (newCurrentQuery?: QueryState) => void;
handleOnUnitsChange: (units: Format['id']) => void; handleOnUnitsChange: (units: Format['id']) => void;
updateAllQueriesOperators: ( updateAllQueriesOperators: (
queryData: Query, queryData: Query,