Skip to content

Commit ea44d05

Browse files
authored
fix: Preserve default select when saving search (#1986)
## Summary This PR fixes a bug which caused searches with the defaultSelectExpression to be saved with an empty `select` value, resulting in no select value appearing when loading the saved search. The fix is to save the default select expression when there is no select value in the `searchedConfig` value (from the URL params), which corresponds to the case in which the default select expression is shown on the (non-saved) search page. ### Screenshots or video Before: https://github.com/user-attachments/assets/2b578dab-2085-4e64-a79c-c2e6e8f085fa After: https://github.com/user-attachments/assets/bf713b86-a454-4fc8-9ed7-5370e2e665e0 ### How to test locally or on Vercel You can reproduce the behavior in the preview environment following the video demo above. ### References - Linear Issue: Closes HDX-3298 - Related PRs:
1 parent 73da48a commit ea44d05

3 files changed

Lines changed: 57 additions & 3 deletions

File tree

.changeset/good-socks-leave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperdx/app": patch
3+
---
4+
5+
fix: Preserve default select when saving search

packages/app/src/DBSearchPage.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
FormEvent,
33
FormEventHandler,
44
memo,
5-
SetStateAction,
65
useCallback,
76
useEffect,
87
useMemo,
@@ -346,6 +345,13 @@ function SaveSearchModalComponent({
346345
const createSavedSearch = useCreateSavedSearch();
347346
const updateSavedSearch = useUpdateSavedSearch();
348347

348+
const { data: sourceObj } = useSource({
349+
id: searchedConfig.source,
350+
kinds: [SourceKind.Log, SourceKind.Trace],
351+
});
352+
const effectiveSelect =
353+
searchedConfig.select || sourceObj?.defaultTableSelectExpression || '';
354+
349355
const onSubmit = (e: FormEvent<HTMLFormElement>) => {
350356
e.preventDefault();
351357

@@ -359,7 +365,7 @@ function SaveSearchModalComponent({
359365
{
360366
id: savedSearchId,
361367
name,
362-
select: searchedConfig.select ?? '',
368+
select: effectiveSelect,
363369
where: searchedConfig.where ?? '',
364370
whereLanguage:
365371
searchedConfig.whereLanguage ?? getStoredLanguage() ?? 'lucene',
@@ -378,7 +384,7 @@ function SaveSearchModalComponent({
378384
createSavedSearch.mutate(
379385
{
380386
name,
381-
select: searchedConfig.select ?? '',
387+
select: effectiveSelect,
382388
where: searchedConfig.where ?? '',
383389
whereLanguage:
384390
searchedConfig.whereLanguage ?? getStoredLanguage() ?? 'lucene',

packages/app/tests/e2e/features/search/saved-search.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,49 @@ test.describe('Saved Search Functionality', () => {
303303
},
304304
);
305305

306+
test(
307+
'should preserve default SELECT when saving a search',
308+
{},
309+
async ({ page }) => {
310+
let savedSearchUrl: string;
311+
312+
await test.step('Create saved search without setting a custom select', async () => {
313+
await searchPage.openSaveSearchModal();
314+
await searchPage.savedSearchModal.saveSearchAndWaitForNavigation(
315+
'Default Select Navigation Test',
316+
);
317+
318+
savedSearchUrl = page.url().split('?')[0];
319+
});
320+
321+
await test.step('Verify default SELECT is loaded', async () => {
322+
const selectEditor = searchPage.getSELECTEditor();
323+
const selectContent = await selectEditor.textContent();
324+
expect(selectContent).toContain(
325+
'Timestamp, ServiceName, SeverityText, Body',
326+
);
327+
});
328+
329+
await test.step('Navigate to dashboards page', async () => {
330+
await page.goto('/dashboards');
331+
await expect(page.getByTestId('dashboard-page')).toBeVisible();
332+
});
333+
334+
await test.step('Navigate back to saved search', async () => {
335+
await page.goto(savedSearchUrl);
336+
await expect(page.getByTestId('search-page')).toBeVisible();
337+
});
338+
339+
await test.step('Verify default SELECT is loaded', async () => {
340+
const selectEditor = searchPage.getSELECTEditor();
341+
const selectContent = await selectEditor.textContent();
342+
expect(selectContent).toContain(
343+
'Timestamp, ServiceName, SeverityText, Body',
344+
);
345+
});
346+
},
347+
);
348+
306349
test(
307350
'should handle navigation via browser back button',
308351
{},

0 commit comments

Comments
 (0)