From 43e2be033310a1bdb640b53c287f6cdf942b48f4 Mon Sep 17 00:00:00 2001 From: Shaheer Kochai Date: Tue, 22 Apr 2025 19:54:03 +0430 Subject: [PATCH] feat: use search v2 component for traces (#7537) * Revert "fix: display same key with multiple data types in filter suggestions by enhancing the deduping logic (#7255)" This reverts commit 1e85981a17a8e715e948308d3e85072d976907d3. * fix: use query search v2 for traces data source to handle multiple data types for the same key * fix(QueryBuilderSearchV2): add user typed option if it doesn't exist in the payload * fix(QueryBuilderSearchV2): increase the height of search dropdown for non-logs data sources * fix: display span scope selector for trace data source * chore: remove the span scope selector from qb search v1 and move the component to search v2 * fix: write test to ensure that we display span scope selector for traces data source * fix: limit converting -> only to log data source * fix: don't display empty suggestion if only spaces are typed * chore: tests for span scope selector * chore: qb search flow (key, operator, value) test cases * refactor: fix the Maximum update depth reached issue while running tests * chore: overall improvements to span scope selector tests --- .../QueryBuilder/components/Query/Query.tsx | 2 +- .../filters/QueryBuilderSearch/index.tsx | 7 - .../QueryBuilderSearchDropdown.tsx | 7 +- .../QueryBuilderSearchV2.styles.scss | 5 + .../QueryBuilderSearchV2.tsx | 44 +++- .../SpanScopeSelector.tsx | 1 + .../__test__/QueryBuilderSearchV2.test.tsx | 196 ++++++++++++++++++ .../__test__/SpanScopeSelector.test.tsx | 165 +++++++++++++++ frontend/src/hooks/queryBuilder/useOptions.ts | 6 +- 9 files changed, 413 insertions(+), 20 deletions(-) rename frontend/src/container/QueryBuilder/filters/{QueryBuilderSearch => QueryBuilderSearchV2}/SpanScopeSelector.tsx (98%) create mode 100644 frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx create mode 100644 frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/SpanScopeSelector.test.tsx diff --git a/frontend/src/container/QueryBuilder/components/Query/Query.tsx b/frontend/src/container/QueryBuilder/components/Query/Query.tsx index 23c5f09528..f1ce6aeaa8 100644 --- a/frontend/src/container/QueryBuilder/components/Query/Query.tsx +++ b/frontend/src/container/QueryBuilder/components/Query/Query.tsx @@ -453,7 +453,7 @@ export const Query = memo(function Query({ )} - {query.dataSource === DataSource.LOGS ? ( + {[DataSource.LOGS, DataSource.TRACES].includes(query.dataSource) ? ( pathname === ROUTES.TRACES_EXPLORER, - [pathname], - ); - const [isEditingTag, setIsEditingTag] = useState(false); const { @@ -489,7 +483,6 @@ function QueryBuilderSearch({ ))} - {isTracesExplorerPage && } ); } diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchDropdown.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchDropdown.tsx index 577b72ff83..c046b1ca4f 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchDropdown.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchDropdown.tsx @@ -2,6 +2,7 @@ import './QueryBuilderSearchV2.styles.scss'; import { Typography } from 'antd'; +import cx from 'classnames'; import { ArrowDown, ArrowUp, @@ -25,6 +26,7 @@ interface ICustomDropdownProps { exampleQueries: TagFilter[]; onChange: (value: TagFilter) => void; currentFilterItem?: ITag; + isLogsDataSource: boolean; } export default function QueryBuilderSearchDropdown( @@ -38,11 +40,14 @@ export default function QueryBuilderSearchDropdown( exampleQueries, options, onChange, + isLogsDataSource, } = props; const userOs = getUserOperatingSystem(); return ( <> -
+
{!currentFilterItem?.key ? (
Suggested Filters
) : !currentFilterItem?.op ? ( diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.styles.scss b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.styles.scss index c7a96456e9..49f04baf0e 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.styles.scss +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.styles.scss @@ -11,6 +11,11 @@ .rc-virtual-list-holder { height: 115px; } + &.non-logs-data-source { + .rc-virtual-list-holder { + height: 256px; + } + } } } diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx index fa4c9aea0c..1c0cc87704 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx @@ -65,6 +65,7 @@ import { } from '../QueryBuilderSearch/utils'; import { filterByOperatorConfig } from '../utils'; import QueryBuilderSearchDropdown from './QueryBuilderSearchDropdown'; +import SpanScopeSelector from './SpanScopeSelector'; import Suggestions from './Suggestions'; export interface ITag { @@ -294,7 +295,8 @@ function QueryBuilderSearchV2( if ( isObject(parsedValue) && parsedValue?.key && - parsedValue?.key?.split(' ').length > 1 + parsedValue?.key?.split(' ').length > 1 && + isLogsDataSource ) { setTags((prev) => [ ...prev, @@ -409,7 +411,13 @@ function QueryBuilderSearchV2( } } }, - [currentFilterItem?.key, currentFilterItem?.op, currentState, searchValue], + [ + currentFilterItem?.key, + currentFilterItem?.op, + currentState, + isLogsDataSource, + searchValue, + ], ); const handleSearch = useCallback((value: string) => { @@ -693,12 +701,29 @@ function QueryBuilderSearchV2( })), ); } else { - setDropdownOptions( - data?.payload?.attributeKeys?.map((key) => ({ + setDropdownOptions([ + // Add user typed option if it doesn't exist in the payload + ...(tagKey.trim().length > 0 && + !data?.payload?.attributeKeys?.some((val) => val.key === tagKey) + ? [ + { + label: tagKey, + value: { + key: tagKey, + dataType: DataTypes.EMPTY, + type: '', + isColumn: false, + isJSON: false, + }, + }, + ] + : []), + // Map existing attribute keys from payload + ...(data?.payload?.attributeKeys?.map((key) => ({ label: key.key, value: key, - })) || [], - ); + })) || []), + ]); } } if (currentState === DropdownState.OPERATOR) { @@ -911,6 +936,11 @@ function QueryBuilderSearchV2( ); }; + const isTracesDataSource = useMemo( + () => query.dataSource === DataSource.TRACES, + [query.dataSource], + ); + return (
+ {isTracesDataSource && }
); } diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/SpanScopeSelector.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector.tsx similarity index 98% rename from frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/SpanScopeSelector.tsx rename to frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector.tsx index 7ff6394123..bdf2d16343 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearch/SpanScopeSelector.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector.tsx @@ -120,6 +120,7 @@ function SpanScopeSelector({ queryName }: SpanScopeSelectorProps): JSX.Element {