Skip to content

Commit a360f96

Browse files
authored
feat(search-bar): Add back contains raw search replacement (#99520)
This PR adds back in the wildcard raw search replacement, since it was removed until the new version of wildcard operators was completed. Ticket: EXP 490
1 parent e8562ac commit a360f96

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed

static/app/components/searchQueryBuilder/index.spec.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4045,6 +4045,54 @@ describe('SearchQueryBuilder', () => {
40454045
screen.getByRole('row', {name: 'span.description:"random value"'})
40464046
).toBeInTheDocument();
40474047
});
4048+
4049+
describe('with wildcard operators enabled', () => {
4050+
it('should replace raw search keys with defined key:contains:value', async () => {
4051+
render(
4052+
<SearchQueryBuilder
4053+
{...defaultProps}
4054+
initialQuery=""
4055+
replaceRawSearchKeys={['span.description']}
4056+
/>,
4057+
{organization: {features: ['search-query-builder-wildcard-operators']}}
4058+
);
4059+
4060+
await userEvent.type(screen.getByRole('textbox'), 'randomValue');
4061+
4062+
await userEvent.click(
4063+
within(screen.getByRole('listbox')).getAllByText('span.description')[0]!
4064+
);
4065+
4066+
expect(
4067+
screen.getByRole('row', {
4068+
name: `span.description:${WildcardOperators.CONTAINS}randomValue`,
4069+
})
4070+
).toBeInTheDocument();
4071+
});
4072+
4073+
it('should replace raw search keys with defined key:contains:"value space', async () => {
4074+
render(
4075+
<SearchQueryBuilder
4076+
{...defaultProps}
4077+
initialQuery=""
4078+
replaceRawSearchKeys={['span.description']}
4079+
/>,
4080+
{organization: {features: ['search-query-builder-wildcard-operators']}}
4081+
);
4082+
4083+
await userEvent.type(screen.getByRole('textbox'), 'random value');
4084+
4085+
await userEvent.click(
4086+
within(screen.getByRole('listbox')).getAllByText('span.description')[0]!
4087+
);
4088+
4089+
expect(
4090+
screen.getByRole('row', {
4091+
name: `span.description:${WildcardOperators.CONTAINS}"random value"`,
4092+
})
4093+
).toBeInTheDocument();
4094+
});
4095+
});
40484096
});
40494097

40504098
describe('matchKeySuggestions', () => {

static/app/components/searchQueryBuilder/tokens/filterKeyListBox/utils.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import type {
1717
FieldDefinitionGetter,
1818
FilterKeySection,
1919
} from 'sentry/components/searchQueryBuilder/types';
20-
import type {Token, TokenResult} from 'sentry/components/searchSyntax/parser';
20+
import {
21+
WildcardOperators,
22+
type Token,
23+
type TokenResult,
24+
} from 'sentry/components/searchSyntax/parser';
2125
import {
2226
getKeyLabel as getFilterKeyLabel,
2327
getKeyName,
@@ -164,6 +168,24 @@ export function createRawSearchFilterIsValueItem(
164168
};
165169
}
166170

171+
export function createRawSearchFilterContainsValueItem(
172+
key: string,
173+
value: string
174+
): RawSearchFilterIsValueItem {
175+
const filter = `${key}:${WildcardOperators.CONTAINS}${escapeFilterValue(value)}`;
176+
177+
return {
178+
key: getEscapedKey(`${key}:${WildcardOperators.CONTAINS}${value}`),
179+
label: <FormattedQuery query={filter} />,
180+
value: filter,
181+
textValue: filter,
182+
hideCheck: true,
183+
showDetailsInOverlay: true,
184+
details: null,
185+
type: 'raw-search-filter-is-value',
186+
};
187+
}
188+
167189
export function createRecentFilterItem({filter}: {filter: TokenResult<Token.FILTER>}) {
168190
const key = getKeyName(filter.key);
169191
return {

static/app/components/searchQueryBuilder/tokens/useSortedFilterKeyItems.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
createAskSeerItem,
1111
createFilterValueItem,
1212
createItem,
13+
createRawSearchFilterContainsValueItem,
1314
createRawSearchFilterIsValueItem,
1415
createRawSearchItem,
1516
} from 'sentry/components/searchQueryBuilder/tokens/filterKeyListBox/utils';
@@ -18,6 +19,7 @@ import type {Tag} from 'sentry/types/group';
1819
import {defined} from 'sentry/utils';
1920
import {FieldKey} from 'sentry/utils/fields';
2021
import {useFuzzySearch} from 'sentry/utils/fuzzySearch';
22+
import useOrganization from 'sentry/utils/useOrganization';
2123

2224
type FilterKeySearchItem = {
2325
description: string;
@@ -139,6 +141,10 @@ export function useSortedFilterKeyItems({
139141
enableAISearch,
140142
} = useSearchQueryBuilder();
141143

144+
const hasWildcardOperators = useOrganization().features.includes(
145+
'search-query-builder-wildcard-operators'
146+
);
147+
142148
const flatKeys = useMemo(() => Object.values(filterKeys), [filterKeys]);
143149

144150
const searchableItems = useMemo<FilterKeySearchItem[]>(() => {
@@ -215,12 +221,17 @@ export function useSortedFilterKeyItems({
215221
!replaceRawSearchKeys?.length;
216222

217223
const rawSearchFilterIsValueItems =
218-
replaceRawSearchKeys?.map(key => {
224+
replaceRawSearchKeys?.flatMap(key => {
219225
const value = inputValue?.includes(' ')
220226
? `"${inputValue.replace(/"/g, '')}"`
221227
: inputValue;
222228

223-
return createRawSearchFilterIsValueItem(key, value);
229+
return [
230+
...(hasWildcardOperators
231+
? [createRawSearchFilterContainsValueItem(key, value)]
232+
: []),
233+
createRawSearchFilterIsValueItem(key, value),
234+
];
224235
}) ?? [];
225236

226237
const rawSearchReplacements: KeySectionItem = {
@@ -292,6 +303,7 @@ export function useSortedFilterKeyItems({
292303
filterValue,
293304
flatKeys,
294305
getFieldDefinition,
306+
hasWildcardOperators,
295307
includeSuggestions,
296308
inputValue,
297309
matchKeySuggestions,

0 commit comments

Comments
 (0)