mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 05:36:03 +08:00
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:
parent
f17608fa10
commit
004f10e73b
3
frontend/public/locales/en-GB/explorer.json
Normal file
3
frontend/public/locales/en-GB/explorer.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"name_of_the_view": "Name of the view"
|
||||||
|
}
|
3
frontend/public/locales/en/explorer.json
Normal file
3
frontend/public/locales/en/explorer.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"name_of_the_view": "Name of the view"
|
||||||
|
}
|
@ -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}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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',
|
||||||
|
};
|
||||||
|
@ -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();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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>,
|
||||||
);
|
);
|
||||||
|
@ -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'];
|
||||||
}
|
}
|
||||||
|
@ -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',
|
||||||
|
@ -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',
|
|
||||||
};
|
|
||||||
|
@ -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';
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
@ -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,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
@ -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) || '';
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user