Save view PRD design changes. (#3480)

* 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: save view prd design changes

* refactor: reverted resetQuery in querybuilder

* refactor: queryParams to query.ts in querybuilder constants

* fix: redirect with saved view is updated

* refactor: removed useffect logic for updating query

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
Rajat Dabade 2023-09-12 11:57:33 +05:30 committed by GitHub
parent 7b4fd55aeb
commit 96adc7f61c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 88 additions and 107 deletions

View File

@ -19,6 +19,7 @@ import {
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 { QueryParams } from 'constants/query';
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';
@ -27,14 +28,10 @@ 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 { useEffect, useState } from 'react'; import { useState } from 'react';
import { useCopyToClipboard } from 'react-use'; import { useCopyToClipboard } from 'react-use';
import { import { ExploreHeaderToolTip, SaveButtonText } from './constants';
ExploreHeaderToolTip,
querySearchParams,
SaveButtonText,
} from './constants';
import MenuItemGenerator from './MenuItemGenerator'; import MenuItemGenerator from './MenuItemGenerator';
import SaveViewWithName from './SaveViewWithName'; import SaveViewWithName from './SaveViewWithName';
import { import {
@ -43,7 +40,7 @@ import {
OffSetCol, OffSetCol,
} from './styles'; } from './styles';
import { ExplorerCardProps } from './types'; import { ExplorerCardProps } from './types';
import { deleteViewHandler, isQueryUpdatedInView } from './utils'; import { deleteViewHandler } from './utils';
function ExplorerCard({ function ExplorerCard({
sourcepage, sourcepage,
@ -51,7 +48,6 @@ function ExplorerCard({
}: ExplorerCardProps): JSX.Element { }: ExplorerCardProps): JSX.Element {
const [isOpen, setIsOpen] = useState<boolean>(false); const [isOpen, setIsOpen] = useState<boolean>(false);
const [, setCopyUrl] = useCopyToClipboard(); const [, setCopyUrl] = useCopyToClipboard();
const [isQueryUpdated, setIsQueryUpdated] = useState<boolean>(false);
const { notifications } = useNotifications(); const { notifications } = useNotifications();
const onCopyUrlHandler = (): void => { const onCopyUrlHandler = (): void => {
@ -62,11 +58,11 @@ function ExplorerCard({
}; };
const { const {
stagedQuery,
currentQuery, currentQuery,
panelType, panelType,
redirectWithQueryBuilderData, redirectWithQueryBuilderData,
updateAllQueriesOperators, updateAllQueriesOperators,
isStagedQueryUpdated,
} = useQueryBuilder(); } = useQueryBuilder();
const { const {
@ -83,10 +79,11 @@ function ExplorerCard({
setIsOpen(newOpen); setIsOpen(newOpen);
}; };
const viewName = const viewName = useGetSearchQueryParam(QueryParams.viewName) || '';
useGetSearchQueryParam(querySearchParams.viewName) || 'Query Builder';
const viewKey = useGetSearchQueryParam(querySearchParams.viewKey) || ''; const viewKey = useGetSearchQueryParam(QueryParams.viewKey) || '';
const isQueryUpdated = isStagedQueryUpdated(viewsData?.data?.data, viewKey);
const { mutateAsync: updateViewAsync } = useUpdateView({ const { mutateAsync: updateViewAsync } = useUpdateView({
compositeQuery: mapCompositeQueryFromQuery(currentQuery, panelType), compositeQuery: mapCompositeQueryFromQuery(currentQuery, panelType),
@ -128,7 +125,6 @@ function ExplorerCard({
}, },
{ {
onSuccess: () => { onSuccess: () => {
setIsQueryUpdated(false);
notifications.success({ notifications.success({
message: 'View Updated Successfully', message: 'View Updated Successfully',
}); });
@ -141,24 +137,6 @@ function ExplorerCard({
); );
}; };
useEffect(() => {
setIsQueryUpdated(
isQueryUpdatedInView({
data: viewsData?.data?.data,
stagedQuery,
viewKey,
currentPanelType: panelType,
}),
);
}, [
currentQuery,
viewsData?.data?.data,
stagedQuery,
stagedQuery?.builder.queryData,
viewKey,
panelType,
]);
const moreOptionMenu: MenuProps = { const moreOptionMenu: MenuProps = {
items: [ items: [
{ {
@ -179,7 +157,7 @@ function ExplorerCard({
<Row align="middle"> <Row align="middle">
<Col span={6}> <Col span={6}>
<Space> <Space>
<Typography>{viewName}</Typography> <Typography>Query Builder</Typography>
<TextToolTip <TextToolTip
url={ExploreHeaderToolTip.url} url={ExploreHeaderToolTip.url}
text={ExploreHeaderToolTip.text} text={ExploreHeaderToolTip.text}
@ -197,7 +175,8 @@ function ExplorerCard({
placeholder="Select a view" placeholder="Select a view"
dropdownStyle={DropDownOverlay} dropdownStyle={DropDownOverlay}
dropdownMatchSelectWidth={false} dropdownMatchSelectWidth={false}
value={null} optionLabelProp="value"
value={viewName || undefined}
> >
{viewsData?.data.data.map((view) => ( {viewsData?.data.data.map((view) => (
<Select.Option key={view.uuid} value={view.name}> <Select.Option key={view.uuid} value={view.name}>

View File

@ -1,3 +1,5 @@
import { QueryParams } from 'constants/query';
export const ExploreHeaderToolTip = { export const ExploreHeaderToolTip = {
url: url:
'https://signoz.io/docs/userguide/query-builder/?utm_source=product&utm_medium=new-query-builder', 'https://signoz.io/docs/userguide/query-builder/?utm_source=product&utm_medium=new-query-builder',
@ -9,12 +11,4 @@ export const SaveButtonText = {
SAVE_VIEW: 'Save view', SAVE_VIEW: 'Save view',
}; };
export type QuerySearchParamNames = 'viewName' | 'viewKey'; export type QuerySearchParamNames = QueryParams.viewName | QueryParams.viewKey;
export const querySearchParams: Record<
QuerySearchParamNames,
QuerySearchParamNames
> = {
viewName: 'viewName',
viewKey: 'viewKey',
};

View File

@ -1,12 +1,11 @@
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 { QueryParams } from 'constants/query';
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder'; import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import { queryParamNamesMap } 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,
@ -119,9 +118,9 @@ export const saveViewHandler = ({
onSuccess: (data) => { onSuccess: (data) => {
refetchAllView(); refetchAllView();
redirectWithQueryBuilderData(mapQueryDataFromApi(compositeQuery), { redirectWithQueryBuilderData(mapQueryDataFromApi(compositeQuery), {
[queryParamNamesMap.panelTypes]: panelType, [QueryParams.panelTypes]: panelType,
[querySearchParams.viewName]: viewName, [QueryParams.viewName]: viewName,
[querySearchParams.viewKey]: data.data.data, [QueryParams.viewKey]: data.data.data,
}); });
notifications.success({ notifications.success({
message: 'View Saved Successfully', message: 'View Saved Successfully',
@ -159,9 +158,9 @@ export const deleteViewHandler = ({
sourcePage, sourcePage,
), ),
{ {
[querySearchParams.viewName]: 'Query Builder', [QueryParams.viewName]: '',
[queryParamNamesMap.panelTypes]: panelType, [QueryParams.panelTypes]: panelType,
[querySearchParams.viewKey]: '', [QueryParams.viewKey]: '',
}, },
); );
} }

View File

@ -18,4 +18,12 @@ export enum QueryParams {
q = 'q', q = 'q',
activeLogId = 'activeLogId', activeLogId = 'activeLogId',
timeRange = 'timeRange', timeRange = 'timeRange',
compositeQuery = 'compositeQuery',
panelTypes = 'panelTypes',
pageSize = 'pageSize',
viewMode = 'viewMode',
selectedFields = 'selectedFields',
linesPerRow = 'linesPerRow',
viewName = 'viewName',
viewKey = 'viewKey',
} }

View File

@ -1,16 +0,0 @@
type QueryParamNames =
| 'compositeQuery'
| 'panelTypes'
| 'pageSize'
| 'viewMode'
| 'selectedFields'
| 'linesPerRow';
export const queryParamNamesMap: Record<QueryParamNames, QueryParamNames> = {
compositeQuery: 'compositeQuery',
panelTypes: 'panelTypes',
pageSize: 'pageSize',
viewMode: 'viewMode',
selectedFields: 'selectedFields',
linesPerRow: 'linesPerRow',
};

View File

@ -1,6 +1,6 @@
import { AlertOutlined, AreaChartOutlined } from '@ant-design/icons'; import { AlertOutlined, AreaChartOutlined } from '@ant-design/icons';
import { Button, Modal, Space } from 'antd'; import { Button, Modal, Space } from 'antd';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames'; import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import history from 'lib/history'; import history from 'lib/history';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
@ -22,9 +22,9 @@ function ExportPanel({
const onCreateAlertsHandler = useCallback(() => { const onCreateAlertsHandler = useCallback(() => {
history.push( history.push(
`${ROUTES.ALERTS_NEW}?${ `${ROUTES.ALERTS_NEW}?${QueryParams.compositeQuery}=${encodeURIComponent(
queryParamNamesMap.compositeQuery JSON.stringify(query),
}=${encodeURIComponent(JSON.stringify(query))}`, )}`,
); );
}, [query]); }, [query]);

View File

@ -8,7 +8,7 @@ import {
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Dropdown, MenuProps, Tooltip, Typography } from 'antd'; import { Dropdown, MenuProps, Tooltip, Typography } from 'antd';
import Spinner from 'components/Spinner'; import Spinner from 'components/Spinner';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames'; import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import useComponentPermission from 'hooks/useComponentPermission'; import useComponentPermission from 'hooks/useComponentPermission';
import history from 'lib/history'; import history from 'lib/history';
@ -73,7 +73,7 @@ function WidgetHeader({
history.push( history.push(
`${window.location.pathname}/new?widgetId=${widgetId}&graphType=${ `${window.location.pathname}/new?widgetId=${widgetId}&graphType=${
widget.panelTypes widget.panelTypes
}&${queryParamNamesMap.compositeQuery}=${encodeURIComponent( }&${QueryParams.compositeQuery}=${encodeURIComponent(
JSON.stringify(widget.query), JSON.stringify(widget.query),
)}`, )}`,
); );
@ -81,9 +81,9 @@ function WidgetHeader({
const onCreateAlertsHandler = useCallback(() => { const onCreateAlertsHandler = useCallback(() => {
history.push( history.push(
`${ROUTES.ALERTS_NEW}?${ `${ROUTES.ALERTS_NEW}?${QueryParams.compositeQuery}=${encodeURIComponent(
queryParamNamesMap.compositeQuery JSON.stringify(widget.query),
}=${encodeURIComponent(JSON.stringify(widget.query))}`, )}`,
); );
}, [widget]); }, [widget]);

View File

@ -5,7 +5,7 @@ import { ColumnsType } from 'antd/lib/table';
import saveAlertApi from 'api/alerts/save'; import saveAlertApi from 'api/alerts/save';
import { ResizeTable } from 'components/ResizeTable'; import { ResizeTable } from 'components/ResizeTable';
import TextToolTip from 'components/TextToolTip'; import TextToolTip from 'components/TextToolTip';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames'; import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import useComponentPermission from 'hooks/useComponentPermission'; import useComponentPermission from 'hooks/useComponentPermission';
import useInterval from 'hooks/useInterval'; import useInterval from 'hooks/useInterval';
@ -76,7 +76,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
history.push( history.push(
`${ROUTES.EDIT_ALERTS}?ruleId=${record.id.toString()}&${ `${ROUTES.EDIT_ALERTS}?ruleId=${record.id.toString()}&${
queryParamNamesMap.compositeQuery QueryParams.compositeQuery
}=${encodeURIComponent(JSON.stringify(compositeQuery))}`, }=${encodeURIComponent(JSON.stringify(compositeQuery))}`,
); );
}) })

View File

@ -1,10 +1,10 @@
import { ArrowLeftOutlined } from '@ant-design/icons'; import { ArrowLeftOutlined } from '@ant-design/icons';
import { Button } from 'antd'; import { Button } from 'antd';
import { QueryParams } from 'constants/query';
import { import {
initialQueryBuilderFormValuesMap, initialQueryBuilderFormValuesMap,
PANEL_TYPES, PANEL_TYPES,
} from 'constants/queryBuilder'; } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam'; import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
@ -38,7 +38,7 @@ function BackButton(): JSX.Element {
const JSONCompositeQuery = encodeURIComponent(JSON.stringify(updatedQuery)); const JSONCompositeQuery = encodeURIComponent(JSON.stringify(updatedQuery));
const path = `${ROUTES.LOGS_EXPLORER}?${queryParamNamesMap.compositeQuery}=${JSONCompositeQuery}`; const path = `${ROUTES.LOGS_EXPLORER}?${QueryParams.compositeQuery}=${JSONCompositeQuery}`;
history.push(path); history.push(path);
}, [history, compositeQuery, updateAllQueriesOperators]); }, [history, compositeQuery, updateAllQueriesOperators]);

View File

@ -1,13 +1,13 @@
import { Tabs, TabsProps } from 'antd'; import { Tabs, TabsProps } from 'antd';
import TabLabel from 'components/TabLabel'; import TabLabel from 'components/TabLabel';
import { AVAILABLE_EXPORT_PANEL_TYPES } from 'constants/panelTypes'; import { AVAILABLE_EXPORT_PANEL_TYPES } from 'constants/panelTypes';
import { QueryParams } from 'constants/query';
import { import {
initialFilters, initialFilters,
initialQueriesMap, initialQueriesMap,
initialQueryBuilderFormValues, initialQueryBuilderFormValues,
PANEL_TYPES, PANEL_TYPES,
} from 'constants/queryBuilder'; } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config'; import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
import ExportPanel from 'container/ExportPanel'; import ExportPanel from 'container/ExportPanel';
import GoToTop from 'container/GoToTop'; import GoToTop from 'container/GoToTop';
@ -50,7 +50,7 @@ function LogsExplorerViews(): JSX.Element {
const { activeLogId, timeRange, onTimeRangeChange } = useCopyLogLink(); const { activeLogId, timeRange, onTimeRangeChange } = useCopyLogLink();
const { queryData: pageSize } = useUrlQueryData( const { queryData: pageSize } = useUrlQueryData(
queryParamNamesMap.pageSize, QueryParams.pageSize,
DEFAULT_PER_PAGE_VALUE, DEFAULT_PER_PAGE_VALUE,
); );

View File

@ -1,9 +1,9 @@
import { PlayCircleFilled } from '@ant-design/icons'; import { PlayCircleFilled } from '@ant-design/icons';
import { QueryParams } from 'constants/query';
import { import {
initialQueryBuilderFormValuesMap, initialQueryBuilderFormValuesMap,
PANEL_TYPES, PANEL_TYPES,
} from 'constants/queryBuilder'; } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { import {
@ -63,7 +63,7 @@ function LogsTopNav(): JSX.Element {
const JSONCompositeQuery = encodeURIComponent(JSON.stringify(compositeQuery)); const JSONCompositeQuery = encodeURIComponent(JSON.stringify(compositeQuery));
const path = `${ROUTES.LIVE_LOGS}?${queryParamNamesMap.compositeQuery}=${JSONCompositeQuery}`; const path = `${ROUTES.LIVE_LOGS}?${QueryParams.compositeQuery}=${JSONCompositeQuery}`;
history.push(path, queryHistoryState); history.push(path, queryHistoryState);
}, [history, panelType, queryClient, stagedQuery]); }, [history, panelType, queryClient, stagedQuery]);

View File

@ -1,5 +1,5 @@
import { QueryParams } from 'constants/query';
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder'; import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import { useIsDarkMode } from 'hooks/useDarkMode'; import { useIsDarkMode } from 'hooks/useDarkMode';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import createQueryParams from 'lib/createQueryParams'; import createQueryParams from 'lib/createQueryParams';
@ -49,9 +49,7 @@ function DashboardGraphSlider({ toggleAddWidget }: Props): JSX.Element {
const queryParams = { const queryParams = {
graphType: name, graphType: name,
widgetId: emptyLayout.i, widgetId: emptyLayout.i,
[queryParamNamesMap.compositeQuery]: JSON.stringify( [QueryParams.compositeQuery]: JSON.stringify(initialQueriesMap.metrics),
initialQueriesMap.metrics,
),
}; };
history.push(`${pathname}/new?${createQueryParams(queryParams)}`); history.push(`${pathname}/new?${createQueryParams(queryParams)}`);

View File

@ -1,5 +1,5 @@
import { Col, Row, Select } from 'antd'; import { Col, Row, Select } from 'antd';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames'; import { QueryParams } from 'constants/query';
import { import {
defaultSelectStyle, defaultSelectStyle,
ITEMS_PER_PAGE_OPTIONS, ITEMS_PER_PAGE_OPTIONS,
@ -14,7 +14,7 @@ function PageSizeSelect({
isShow, isShow,
}: PageSizeSelectProps): JSX.Element | null { }: PageSizeSelectProps): JSX.Element | null {
const { redirectWithQuery, queryData: pageSize } = useUrlQueryData<number>( const { redirectWithQuery, queryData: pageSize } = useUrlQueryData<number>(
queryParamNamesMap.pageSize, QueryParams.pageSize,
ITEMS_PER_PAGE_OPTIONS[0], ITEMS_PER_PAGE_OPTIONS[0],
); );

View File

@ -1,4 +1,4 @@
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames'; import { QueryParams } from 'constants/query';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { Query } from 'types/api/queryBuilder/queryBuilderData'; import { Query } from 'types/api/queryBuilder/queryBuilderData';
@ -7,7 +7,7 @@ export const useGetCompositeQueryParam = (): Query | null => {
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
return useMemo(() => { return useMemo(() => {
const compositeQuery = urlQuery.get(queryParamNamesMap.compositeQuery); const compositeQuery = urlQuery.get(QueryParams.compositeQuery);
let parsedCompositeQuery: Query | null = null; let parsedCompositeQuery: Query | null = null;
try { try {

View File

@ -1,5 +1,5 @@
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import { useMemo } from 'react'; import { useMemo } from 'react';
@ -9,7 +9,7 @@ export const useGetPanelTypesQueryParam = <T extends PANEL_TYPES | undefined>(
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
return useMemo(() => { return useMemo(() => {
const panelTypeQuery = urlQuery.get(queryParamNamesMap.panelTypes); const panelTypeQuery = urlQuery.get(QueryParams.panelTypes);
return panelTypeQuery ? JSON.parse(panelTypeQuery) : defaultPanelType; return panelTypeQuery ? JSON.parse(panelTypeQuery) : defaultPanelType;
}, [urlQuery, defaultPanelType]); }, [urlQuery, defaultPanelType]);

View File

@ -1,6 +1,5 @@
import { querySearchParams } from 'components/ExplorerCard/constants'; import { QueryParams } from 'constants/query';
import { initialAutocompleteData, PANEL_TYPES } from 'constants/queryBuilder'; import { initialAutocompleteData, PANEL_TYPES } from 'constants/queryBuilder';
import { queryParamNamesMap } 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';
@ -23,9 +22,9 @@ export const useHandleExplorerTabChange = (): {
updateQueriesData, updateQueriesData,
} = useQueryBuilder(); } = useQueryBuilder();
const viewName = useGetSearchQueryParam(querySearchParams.viewName) || ''; const viewName = useGetSearchQueryParam(QueryParams.viewName) || '';
const viewKey = useGetSearchQueryParam(querySearchParams.viewKey) || ''; const viewKey = useGetSearchQueryParam(QueryParams.viewKey) || '';
const getUpdateQuery = useCallback( const getUpdateQuery = useCallback(
(newPanelType: PANEL_TYPES): Query => { (newPanelType: PANEL_TYPES): Query => {
@ -60,12 +59,12 @@ export const useHandleExplorerTabChange = (): {
const query = currentQueryData?.query || getUpdateQuery(newPanelType); const query = currentQueryData?.query || getUpdateQuery(newPanelType);
redirectWithQueryBuilderData(query, { redirectWithQueryBuilderData(query, {
[queryParamNamesMap.panelTypes]: newPanelType, [QueryParams.panelTypes]: newPanelType,
[querySearchParams.viewName]: currentQueryData?.name || viewName, [QueryParams.viewName]: currentQueryData?.name || viewName,
[querySearchParams.viewKey]: currentQueryData?.uuid || viewKey, [QueryParams.viewKey]: currentQueryData?.uuid || viewKey,
}); });
}, },
[getUpdateQuery, panelType, redirectWithQueryBuilderData, viewKey, viewName], [panelType, getUpdateQuery, redirectWithQueryBuilderData, viewName, viewKey],
); );
return { handleExplorerTabChange }; return { handleExplorerTabChange };

View File

@ -1,3 +1,5 @@
import { isQueryUpdatedInView } from 'components/ExplorerCard/utils';
import { QueryParams } from 'constants/query';
import { import {
alphabet, alphabet,
baseAutoCompleteIdKeysOrder, baseAutoCompleteIdKeysOrder,
@ -13,7 +15,6 @@ import {
MAX_QUERIES, MAX_QUERIES,
PANEL_TYPES, PANEL_TYPES,
} from 'constants/queryBuilder'; } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam'; import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval'; import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
@ -42,6 +43,7 @@ import {
Query, Query,
QueryState, QueryState,
} from 'types/api/queryBuilder/queryBuilderData'; } from 'types/api/queryBuilder/queryBuilderData';
import { ViewProps } from 'types/api/saveViews/types';
import { EQueryType } from 'types/common/dashboard'; import { EQueryType } from 'types/common/dashboard';
import { import {
DataSource, DataSource,
@ -73,6 +75,7 @@ export const QueryBuilderContext = createContext<QueryBuilderContextType>({
updateQueriesData: () => initialQueriesMap.metrics, updateQueriesData: () => initialQueriesMap.metrics,
initQueryBuilderData: () => {}, initQueryBuilderData: () => {},
handleOnUnitsChange: () => {}, handleOnUnitsChange: () => {},
isStagedQueryUpdated: () => false,
}); });
export function QueryBuilderProvider({ export function QueryBuilderProvider({
@ -449,6 +452,17 @@ export function QueryBuilderProvider({
[updateQueryBuilderData], [updateQueryBuilderData],
); );
const isStagedQueryUpdated = useCallback(
(viewData: ViewProps[] | undefined, viewKey: string): boolean =>
isQueryUpdatedInView({
currentPanelType: panelType,
data: viewData,
stagedQuery,
viewKey,
}),
[panelType, stagedQuery],
);
const redirectWithQueryBuilderData = useCallback( const redirectWithQueryBuilderData = useCallback(
(query: Partial<Query>, searchParams?: Record<string, unknown>) => { (query: Partial<Query>, searchParams?: Record<string, unknown>) => {
const queryType = const queryType =
@ -481,7 +495,7 @@ export function QueryBuilderProvider({
}; };
urlQuery.set( urlQuery.set(
queryParamNamesMap.compositeQuery, QueryParams.compositeQuery,
encodeURIComponent(JSON.stringify(currentGeneratedQuery)), encodeURIComponent(JSON.stringify(currentGeneratedQuery)),
); );
@ -613,6 +627,7 @@ export function QueryBuilderProvider({
updateQueriesData, updateQueriesData,
initQueryBuilderData, initQueryBuilderData,
handleOnUnitsChange, handleOnUnitsChange,
isStagedQueryUpdated,
}), }),
[ [
query, query,
@ -635,6 +650,7 @@ export function QueryBuilderProvider({
updateQueriesData, updateQueriesData,
initQueryBuilderData, initQueryBuilderData,
handleOnUnitsChange, handleOnUnitsChange,
isStagedQueryUpdated,
], ],
); );

View File

@ -1,8 +1,8 @@
import { notification } from 'antd'; import { notification } from 'antd';
import updateDashboardApi from 'api/dashboard/update'; import updateDashboardApi from 'api/dashboard/update';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval'; import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval';
import history from 'lib/history'; import history from 'lib/history';
@ -88,7 +88,7 @@ export const SaveDashboard = ({
}; };
const allLayout = getAllLayout(); const allLayout = getAllLayout();
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const compositeQuery = params.get(queryParamNamesMap.compositeQuery); const compositeQuery = params.get(QueryParams.compositeQuery);
const { maxTime, minTime } = store.getState().globalTime; const { maxTime, minTime } = store.getState().globalTime;
const query = compositeQuery const query = compositeQuery
? updateStepInterval( ? updateStepInterval(

View File

@ -8,6 +8,7 @@ import {
Query, Query,
QueryState, QueryState,
} from 'types/api/queryBuilder/queryBuilderData'; } from 'types/api/queryBuilder/queryBuilderData';
import { ViewProps } from 'types/api/saveViews/types';
import { EQueryType } from './dashboard'; import { EQueryType } from './dashboard';
@ -204,6 +205,10 @@ export type QueryBuilderContextType = {
) => QueryBuilderData[T][number], ) => QueryBuilderData[T][number],
) => Query; ) => Query;
initQueryBuilderData: (query: Query) => void; initQueryBuilderData: (query: Query) => void;
isStagedQueryUpdated: (
viewData: ViewProps[] | undefined,
viewKey: string,
) => boolean;
}; };
export type QueryAdditionalFilter = { export type QueryAdditionalFilter = {

View File

@ -1,6 +1,5 @@
import { QueryParams } from 'constants/query'; import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { generatePath } from 'react-router-dom'; import { generatePath } from 'react-router-dom';
import { Query } from 'types/api/queryBuilder/queryBuilderData'; import { Query } from 'types/api/queryBuilder/queryBuilderData';
@ -19,5 +18,5 @@ export const generateExportToDashboardLink = ({
`${generatePath(ROUTES.DASHBOARD, { `${generatePath(ROUTES.DASHBOARD, {
dashboardId, dashboardId,
})}/new?${QueryParams.graphType}=${panelType}&${QueryParams.widgetId}=empty&${ })}/new?${QueryParams.graphType}=${panelType}&${QueryParams.widgetId}=empty&${
queryParamNamesMap.compositeQuery QueryParams.compositeQuery
}=${encodeURIComponent(JSON.stringify(query))}`; }=${encodeURIComponent(JSON.stringify(query))}`;