Skip to content

Commit

Permalink
Merge branch 'main' into SIG-2095
Browse files Browse the repository at this point in the history
  • Loading branch information
SagarRajput-7 authored Dec 26, 2024
2 parents bd18942 + d2aa1cf commit ba45dde
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 70 deletions.
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@
"xml2js": "0.5.0",
"phin": "^3.7.1",
"body-parser": "1.20.3",
"http-proxy-middleware": "3.0.3"
"http-proxy-middleware": "3.0.3",
"cross-spawn": "7.0.5"
}
}
14 changes: 13 additions & 1 deletion frontend/src/container/ExplorerOptions/ExplorerOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ function ExplorerOptions({
panelType,
isStagedQueryUpdated,
redirectWithQueryBuilderData,
isDefaultQuery,
} = useQueryBuilder();

const handleSaveViewModalToggle = (): void => {
Expand Down Expand Up @@ -478,6 +479,11 @@ function ExplorerOptions({
] = useState(false);

useEffect(() => {
// If the query is not the default query, don't set the recently used saved view
if (!isDefaultQuery({ currentQuery, sourcePage: sourcepage })) {
return;
}

const parsedPreservedView = JSON.parse(
localStorage.getItem(PRESERVED_VIEW_LOCAL_STORAGE_KEY) || '{}',
);
Expand All @@ -499,12 +505,18 @@ function ExplorerOptions({
setIsRecentlyUsedSavedViewSelected(false);
}

return (): void => clearTimeout(timeoutId);
// eslint-disable-next-line consistent-return
return (): void => {
clearTimeout(timeoutId);
};
}, [
PRESERVED_VIEW_LOCAL_STORAGE_KEY,
PRESERVED_VIEW_TYPE,
currentQuery,
isDefaultQuery,
isRecentlyUsedSavedViewSelected,
onMenuItemSelectHandler,
sourcepage,
viewKey,
viewName,
viewsData?.data?.data,
Expand Down
64 changes: 45 additions & 19 deletions frontend/src/container/TracesExplorer/ListView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch';
import NoLogs from 'container/NoLogs/NoLogs';
import { useOptionsMenu } from 'container/OptionsMenu';
import { CustomTimeType } from 'container/TopNav/DateTimeSelectionV2/config';
import TraceExplorerControls from 'container/TracesExplorer/Controls';
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { Pagination } from 'hooks/queryPagination';
import { getDefaultPaginationConfig } from 'hooks/queryPagination/utils';
import useDragColumns from 'hooks/useDragColumns';
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
import useUrlQueryData from 'hooks/useUrlQueryData';
Expand All @@ -32,12 +34,19 @@ interface ListViewProps {
}

function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
const { stagedQuery, panelType } = useQueryBuilder();
const {
stagedQuery,
panelType: panelTypeFromQueryBuilder,
} = useQueryBuilder();

const { selectedTime: globalSelectedTime, maxTime, minTime } = useSelector<
AppState,
GlobalReducer
>((state) => state.globalTime);
const panelType = panelTypeFromQueryBuilder || PANEL_TYPES.LIST;

const {
selectedTime: globalSelectedTime,
maxTime,
minTime,
loading: timeRangeUpdateLoading,
} = useSelector<AppState, GlobalReducer>((state) => state.globalTime);

const { options, config } = useOptionsMenu({
storageKey: LOCALSTORAGE.TRACES_LIST_OPTIONS,
Expand All @@ -55,34 +64,51 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
const { queryData: paginationQueryData } = useUrlQueryData<Pagination>(
QueryParams.pagination,
);
const paginationConfig =
paginationQueryData ?? getDefaultPaginationConfig(PER_PAGE_OPTIONS);

const queryKey = useMemo(
() => [
REACT_QUERY_KEY.GET_QUERY_RANGE,
globalSelectedTime,
maxTime,
minTime,
stagedQuery,
panelType,
paginationConfig,
options?.selectColumns,
],
[
stagedQuery,
panelType,
globalSelectedTime,
paginationConfig,
options?.selectColumns,
maxTime,
minTime,
],
);

const { data, isFetching, isLoading, isError } = useGetQueryRange(
{
query: stagedQuery || initialQueriesMap.traces,
graphType: panelType || PANEL_TYPES.LIST,
selectedTime: 'GLOBAL_TIME',
globalSelectedInterval: globalSelectedTime,
graphType: panelType,
selectedTime: 'GLOBAL_TIME' as const,
globalSelectedInterval: globalSelectedTime as CustomTimeType,
params: {
dataSource: 'traces',
},
tableParams: {
pagination: paginationQueryData,
pagination: paginationConfig,
selectColumns: options?.selectColumns,
},
},
DEFAULT_ENTITY_VERSION,
{
queryKey: [
REACT_QUERY_KEY.GET_QUERY_RANGE,
globalSelectedTime,
maxTime,
minTime,
stagedQuery,
panelType,
paginationQueryData,
options?.selectColumns,
],
queryKey,
enabled:
// don't make api call while the time range state in redux is loading
!timeRangeUpdateLoading &&
!!stagedQuery &&
panelType === PANEL_TYPES.LIST &&
!!options?.selectColumns?.length,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ describe('Logs Explorer Tests', () => {
const { queryAllByText } = render(
<QueryBuilderContext.Provider
value={{
isDefaultQuery: (): boolean => false,
currentQuery: {
...initialQueriesMap.metrics,
builder: {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/pages/TracesExplorer/Filter/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ export function Filter(props: FilterProps): JSX.Element {
selectedFilters,
});
}

if (isEqual(currentQuery, preparedQuery) && !props?.resetAll) {
return;
}
redirectWithQueryBuilderData(preparedQuery);
},
[currentQuery, redirectWithQueryBuilderData, selectedFilters],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ jest.mock('container/OptionsMenu/useOptionsMenu', () => ({
default: (): any => optionMenuReturn,
}));

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: (): any => ({
loading: false,
}),
}));

describe('TracesExplorer - Filters', () => {
// Initial filter panel rendering
// Test the initial state like which filters section are opened, default state of duration slider, etc.
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/TracesExplorer/__test__/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export const compositeQuery: Query = {
export const redirectWithQueryBuilderData = jest.fn();

export const qbProviderValue = {
isDefaultQuery: jest.fn(() => false),
currentQuery: {
...initialQueriesMap.traces,
builder: {
Expand Down
95 changes: 91 additions & 4 deletions frontend/src/providers/QueryBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName';
import { getOperatorsBySourceAndPanelType } from 'lib/newQueryBuilder/getOperatorsBySourceAndPanelType';
import { replaceIncorrectObjectFields } from 'lib/replaceIncorrectObjectFields';
import { cloneDeep, get, merge, set } from 'lodash-es';
import { cloneDeep, get, isEqual, merge, set } from 'lodash-es';
import {
createContext,
PropsWithChildren,
Expand All @@ -53,6 +53,7 @@ import { ViewProps } from 'types/api/saveViews/types';
import { EQueryType } from 'types/common/dashboard';
import {
DataSource,
IsDefaultQueryProps,
QueryBuilderContextType,
QueryBuilderData,
} from 'types/common/queryBuilder';
Expand Down Expand Up @@ -87,6 +88,7 @@ export const QueryBuilderContext = createContext<QueryBuilderContextType>({
initQueryBuilderData: () => {},
handleOnUnitsChange: () => {},
isStagedQueryUpdated: () => false,
isDefaultQuery: () => false,
});

export function QueryBuilderProvider({
Expand All @@ -95,7 +97,8 @@ export function QueryBuilderProvider({
const urlQuery = useUrlQuery();
const history = useHistory();
const location = useLocation();
const currentPathnameRef = useRef<string | null>(null);

const currentPathnameRef = useRef<string | null>(location.pathname);

const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
Expand Down Expand Up @@ -249,6 +252,88 @@ export function QueryBuilderProvider({
[getElementWithActualOperator],
);

const extractRelevantKeys = useCallback(
(queryData: IBuilderQuery): IBuilderQuery => {
const {
dataSource,
queryName,
aggregateOperator,
aggregateAttribute,
timeAggregation,
spaceAggregation,
functions,
filters,
expression,
disabled,
stepInterval,
having,
groupBy,
legend,
} = queryData;

return {
dataSource,
queryName,
aggregateOperator,
// remove id from aggregateAttribute
aggregateAttribute: {
...aggregateAttribute,
id: '',
},
timeAggregation,
spaceAggregation,
functions,
filters,
expression,
disabled,
stepInterval,
having,
groupBy,
legend,
// set to default values
orderBy: [],
limit: null,
reduceTo: 'avg',
};
},
[],
);

const isDefaultQuery = useCallback(
({ currentQuery, sourcePage }: IsDefaultQueryProps): boolean => {
// Get default query with updated operators
const defaultQuery = updateAllQueriesOperators(
initialQueriesMap[sourcePage],
PANEL_TYPES.LIST,
sourcePage,
);

// Early return if query types don't match
if (currentQuery.queryType !== defaultQuery.queryType) {
return false;
}

// Only compare builder queries
if (currentQuery.queryType !== EQueryType.QUERY_BUILDER) {
return false;
}

// If there is more than one query, then it is not a default query
if (currentQuery.builder.queryData.length > 1) {
return false;
}

const currentBuilderData = extractRelevantKeys(
currentQuery.builder.queryData[0],
);
const defaultBuilderData = extractRelevantKeys(
defaultQuery.builder.queryData[0],
);

return isEqual(currentBuilderData, defaultBuilderData);
},
[updateAllQueriesOperators, extractRelevantKeys],
);
const updateQueriesData = useCallback(
<T extends keyof QueryBuilderData>(
query: Query,
Expand Down Expand Up @@ -814,14 +899,14 @@ export function QueryBuilderProvider({
};

useEffect(() => {
if (stagedQuery && location.pathname !== currentPathnameRef.current) {
if (location.pathname !== currentPathnameRef.current) {
currentPathnameRef.current = location.pathname;

setStagedQuery(null);
// reset the last used query to 0 when navigating away from the page
setLastUsedQuery(0);
}
}, [location, stagedQuery, currentQuery]);
}, [location.pathname]);

const handleOnUnitsChange = useCallback(
(unit: string) => {
Expand Down Expand Up @@ -883,6 +968,7 @@ export function QueryBuilderProvider({
handleRunQuery,
resetQuery,
updateAllQueriesOperators,
isDefaultQuery,
updateQueriesData,
initQueryBuilderData,
handleOnUnitsChange,
Expand All @@ -909,6 +995,7 @@ export function QueryBuilderProvider({
redirectWithQueryBuilderData,
handleRunQuery,
updateAllQueriesOperators,
isDefaultQuery,
updateQueriesData,
initQueryBuilderData,
handleOnUnitsChange,
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/types/common/queryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,15 @@ export type QueryBuilderContextType = {
viewData: ViewProps[] | undefined,
viewKey: string,
) => boolean;
isDefaultQuery: (props: IsDefaultQueryProps) => boolean;
};

export type QueryAdditionalFilter = {
field: keyof IBuilderQuery;
text: string;
};

export type IsDefaultQueryProps = {
currentQuery: Query;
sourcePage: DataSource;
};
Loading

0 comments on commit ba45dde

Please sign in to comment.