diff --git a/packages/app/src/DBSearchPage.tsx b/packages/app/src/DBSearchPage.tsx index 6a1cdd8e..204b47ce 100644 --- a/packages/app/src/DBSearchPage.tsx +++ b/packages/app/src/DBSearchPage.tsx @@ -409,7 +409,7 @@ function SaveSearchModalComponent({ const onSubmit = (e: FormEvent) => { e.preventDefault(); - handleSubmit(({ name }) => { + handleSubmit(async ({ name }) => { if (isUpdate) { if (savedSearchId == null) { throw new Error('savedSearchId is required for update'); @@ -432,11 +432,20 @@ function SaveSearchModalComponent({ onSuccess: () => { onClose(); }, + onError: error => { + console.error('Error updating saved search:', error); + notifications.show({ + color: 'red', + title: 'Error', + message: + 'An error occurred while updating your saved search. Please try again.', + }); + }, }, ); } else { - createSavedSearch.mutate( - { + try { + const savedSearch = await createSavedSearch.mutateAsync({ name, select: effectiveSelect, where: searchedConfig.where ?? '', @@ -446,18 +455,25 @@ function SaveSearchModalComponent({ orderBy: searchedConfig.orderBy ?? '', filters: searchedConfig.filters ?? [], tags: tags, - }, - { - onSuccess: savedSearch => { - router.push(`/search/${savedSearch.id}${window.location.search}`); - onClose(); - }, - }, - ); + }); + + router.push(`/search/${savedSearch.id}${window.location.search}`); + onClose(); + } catch (error) { + console.error('Error creating saved search:', error); + notifications.show({ + color: 'red', + title: 'Error', + message: + 'An error occurred while saving your search. Please try again.', + }); + } } })(); }; + const isPending = createSavedSearch.isPending || updateSavedSearch.isPending; + const { data: chartConfig } = useSearchedConfigToChartConfig(searchedConfig); return ( @@ -572,6 +588,7 @@ function SaveSearchModalComponent({ variant="primary" type="submit" disabled={!formState.isValid} + loading={isPending} > {isUpdate ? 'Update' : 'Save'} @@ -869,7 +886,7 @@ function DBSearchPage() { where: searchedConfig.where || '', whereLanguage: searchedConfig.whereLanguage ?? getStoredLanguage() ?? 'lucene', - source: searchedConfig.source || defaultSourceId, + source: searchedConfig.source || (savedSearchId ? '' : defaultSourceId), filters: searchedConfig.filters ?? [], orderBy: searchedConfig.orderBy ?? '', }, @@ -1619,16 +1636,18 @@ function DBSearchPage() { - { - updateSavedSearch.mutate({ - id: savedSearch.id, - name: editedName, - }); - }} - /> +
+ { + updateSavedSearch.mutate({ + id: savedSearch.id, + name: editedName, + }); + }} + /> +
(); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['saved-search'] }); + return queryClient.invalidateQueries({ queryKey: ['saved-search'] }); }, }); } diff --git a/packages/app/tests/e2e/components/SavedSearchModalComponent.ts b/packages/app/tests/e2e/components/SavedSearchModalComponent.ts index 7ed6b040..c6fe1964 100644 --- a/packages/app/tests/e2e/components/SavedSearchModalComponent.ts +++ b/packages/app/tests/e2e/components/SavedSearchModalComponent.ts @@ -9,6 +9,7 @@ export class SavedSearchModalComponent { readonly page: Page; private readonly modal: Locator; private readonly nameInput: Locator; + private readonly savedSearchNameTitle: Locator; private readonly submitButton: Locator; private readonly addTagButton: Locator; @@ -16,6 +17,9 @@ export class SavedSearchModalComponent { this.page = page; this.modal = page.locator('[data-testid="save-search-modal"]'); this.nameInput = page.locator('[data-testid="save-search-name-input"]'); + this.savedSearchNameTitle = page.locator( + '[data-testid="saved-search-name"]', + ); this.submitButton = page.locator( '[data-testid="save-search-submit-button"]', ); @@ -98,6 +102,9 @@ export class SavedSearchModalComponent { // Wait for modal to fully close await expect(this.container).toBeHidden(); + + await expect(this.savedSearchNameTitle).toBeVisible({ timeout: 5000 }); + await expect(this.savedSearchNameTitle).toHaveText(name, { timeout: 5000 }); } /** diff --git a/packages/app/tests/e2e/features/search/saved-search.spec.ts b/packages/app/tests/e2e/features/search/saved-search.spec.ts index 81fdb275..7fa051b4 100644 --- a/packages/app/tests/e2e/features/search/saved-search.spec.ts +++ b/packages/app/tests/e2e/features/search/saved-search.spec.ts @@ -263,6 +263,10 @@ test.describe('Saved Search Functionality', () => { // Wait for the search page to load await expect(page.getByTestId('search-page')).toBeVisible(); + await expect(searchPage.savedSearchNameTitle).toBeVisible(); + await expect(searchPage.savedSearchNameTitle).toHaveText( + 'Info Logs Navigation Test', + ); }); await test.step('Verify saved search loaded and executed automatically', async () => { diff --git a/packages/app/tests/e2e/page-objects/SearchPage.ts b/packages/app/tests/e2e/page-objects/SearchPage.ts index 60eb3af6..8d066373 100644 --- a/packages/app/tests/e2e/page-objects/SearchPage.ts +++ b/packages/app/tests/e2e/page-objects/SearchPage.ts @@ -23,6 +23,7 @@ export class SearchPage { readonly infrastructure: InfrastructurePanelComponent; readonly filters: FilterComponent; readonly savedSearchModal: SavedSearchModalComponent; + readonly savedSearchNameTitle: Locator; readonly alertModal: SearchPageAlertModalComponent; readonly defaultTimeout: number = 3000; private readonly alertsButtonLocator: Locator; @@ -53,6 +54,9 @@ export class SearchPage { this.savedSearchModal = new SavedSearchModalComponent(page); this.alertModal = new SearchPageAlertModalComponent(page); this.alertsButtonLocator = page.getByTestId('alerts-button'); + this.savedSearchNameTitle = page.locator( + '[data-testid="saved-search-name"]', + ); // Define page-specific locators this.searchForm = page.getByTestId('search-form');