diff --git a/e2e/tests/journeys.spec.ts b/e2e/tests/journeys.spec.ts
index 15744d8..ae585ee 100644
--- a/e2e/tests/journeys.spec.ts
+++ b/e2e/tests/journeys.spec.ts
@@ -309,6 +309,19 @@ test('school type and gender switch straight to another value', async ({ page })
* School type offers six groups a parent recognises, and Faith sits beside it.
* Data-invariant: asserts what every returned school is, never how many.
*/
+// Clear all once dropped the search with the filters, which sent desktop back
+// to the home page instead of to the unfiltered results.
+test('Clear all removes the filters and keeps the search', async ({ page }) => {
+ await page.goto('/?search=school&phase=primary');
+ const row = page.getByRole('group', { name: 'Filters', exact: true });
+ await expect(schoolLinks(page).first()).toBeVisible({ timeout: 15_000 });
+ await row.getByRole('button', { name: 'Clear all', exact: true }).click();
+ await expect(page).not.toHaveURL(/[?&]phase=/);
+ await expect(page).toHaveURL(/[?&]search=school(&|$)/);
+ await expect(schoolLinks(page).first()).toBeVisible();
+ await expect(row.getByRole('button', { name: 'Clear all', exact: true })).toHaveCount(0);
+});
+
test('school type groups and the faith filter narrow to what they name', async ({ page }) => {
await page.goto('/?search=school');
const type = page.getByRole('combobox', { name: 'School type', exact: true });
diff --git a/nextjs-app/__tests__/components/ResultsToolbar.test.tsx b/nextjs-app/__tests__/components/ResultsToolbar.test.tsx
index 105b9d7..fcd3d44 100644
--- a/nextjs-app/__tests__/components/ResultsToolbar.test.tsx
+++ b/nextjs-app/__tests__/components/ResultsToolbar.test.tsx
@@ -1,4 +1,4 @@
-import { act, fireEvent, render, screen } from '@testing-library/react';
+import { act, fireEvent, render, screen, within } from '@testing-library/react';
import { HomeView } from '@/components/HomeView';
import { FilterBar } from '@/components/FilterBar';
import { fetchSchools } from '@/lib/api';
@@ -175,3 +175,24 @@ describe('the results list', () => {
expect(screen.queryByText('Search: southmead')).not.toBeInTheDocument();
});
});
+
+describe('the desktop Clear all', () => {
+ const row = () => screen.getByRole('group', { name: 'Filters' });
+
+ it('removes the filters and keeps the search, rather than going home', () => {
+ params = new URLSearchParams('postcode=SW196AR&radius=3&phase=primary&school_type=council&local_authority=Wandsworth');
+ render();
+ fireEvent.click(within(row()).getByRole('button', { name: 'Clear all' }));
+ const pushed = push.mock.calls.at(-1)![0] as string;
+ const next = new URLSearchParams(pushed.split('?')[1]);
+ expect(next.get('postcode')).toBe('SW196AR');
+ expect(next.get('radius')).toBe('3');
+ for (const key of ['phase', 'school_type', 'local_authority']) expect(next.get(key)).toBeNull();
+ });
+
+ it('is not offered when only a search is applied', () => {
+ params = new URLSearchParams('search=southmead');
+ render();
+ expect(within(row()).queryByRole('button', { name: /^Clear/ })).not.toBeInTheDocument();
+ });
+});
diff --git a/nextjs-app/components/FilterBar.tsx b/nextjs-app/components/FilterBar.tsx
index 8474d4e..3c4d30a 100644
--- a/nextjs-app/components/FilterBar.tsx
+++ b/nextjs-app/components/FilterBar.tsx
@@ -377,31 +377,13 @@ export function FilterBar({
updateURL({ ...cleared, [key]: value });
};
- // Every filter at once, keeping the search and its distance: what "Clear
- // all" means beside the applied filters, where the search is not one of them.
+ // Every filter at once, keeping the search and its distance. The search is
+ // what the results answer, not a filter on them: clearing it too used to
+ // send desktop back to the home page.
const handleClearFilterValues = () => {
updateURL(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
};
- const handleClearFilters = () => {
- setOmniValue("");
- pendingQueryRef.current = "";
- startTransition(() => {
- router.push(pathname);
- });
- };
-
- const hasActiveFilters =
- currentSearch ||
- currentLA ||
- currentType ||
- currentFaith ||
- currentPhase ||
- currentPostcode ||
- currentGender ||
- currentAdmissionsPolicy ||
- currentHasSixthForm;
-
/*
* A filter's options come from the full lists, not from the results: the
* results have already been narrowed by that filter, so scoping to them
@@ -844,14 +826,14 @@ export function FilterBar({
/>
- {hasActiveFilters && (
+ {appliedCount > 0 && (
)}