Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions lxl-web/src/lib/components/find/SearchResultSort.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { page } from '$app/state';
import { SvelteURLSearchParams } from 'svelte/reactivity';
import BiSortDown from '~icons/bi/sort-down';
import BiChevronDown from '~icons/bi/chevron-down';

const sortOrder = $derived(page.url.searchParams.get('_sort'));
const sortOptions = [
let sortOrder = $derived(page.url.searchParams.get('_sort') || '');

const sortOptions = $derived([
{ value: '', label: page.data.t('sort.relevancy') },
{ value: `_sortKeyByLang.${page.data.locale}`, label: page.data.t('sort.alphaAsc') },
{ value: `-_sortKeyByLang.${page.data.locale}`, label: page.data.t('sort.alphaDesc') },
Expand All @@ -21,16 +24,18 @@
value: '-reverseLinks.totalItemsByRelation.itemOf.instanceOf',
label: page.data.t('sort.holdingsDesc')
}
];
]);

function handleSortChange(e: Event) {
const value = (e.target as HTMLSelectElement).value;
let searchParams = page.url.searchParams;
let searchParams = new SvelteURLSearchParams(page.url.searchParams);
searchParams.set('_sort', value);
if (searchParams.has('_offset')) {
searchParams.set('_offset', '0');
}
goto(`${page.url.pathname}?${searchParams.toString()}`, { invalidate: ['app:search'] });
goto(resolve(`${page.url.pathname}?${searchParams.toString()}`), {
invalidate: ['app:search']
});
}
</script>

Expand All @@ -44,12 +49,13 @@
</span>
<select
id="search-sort"
bind:value={sortOrder}
class="btn btn-primary w-px sm:w-auto"
form="search-form"
onchange={handleSortChange}
>
{#each sortOptions as option (option.value)}
<option value={option.value} selected={option.value === sortOrder}>{option.label}</option>
<option value={option.value}>{option.label}</option>
{/each}
</select>
<span class="text-subtle pointer-events-none absolute top-0 right-1.5 py-2.5 text-sm">
Expand Down
12 changes: 11 additions & 1 deletion lxl-web/src/lib/components/supersearch/SuperSearchWrapper.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { mount, onMount, onDestroy, unmount, tick } from 'svelte';
import { page } from '$app/state';
import { goto, onNavigate, pushState } from '$app/navigation';
import { afterNavigate, goto, onNavigate, pushState } from '$app/navigation';
import {
type ChangeEvent,
type DebouncedWaitFunction,
Expand Down Expand Up @@ -129,6 +129,7 @@
let cursor = $derived(selection?.head || 0);
let isHomeRoute = $derived(page.route.id === '/(app)/[[lang=lang]]');
let isFindRoute = $derived(page.route.id === '/(app)/[[lang=lang]]/find');
let currentSort = $derived(page.url.searchParams.get('_sort') || '');

let superSearch = $state<ReturnType<typeof SuperSearch>>();

Expand Down Expand Up @@ -194,6 +195,14 @@
};
});

// manually fetch data again after sort change to update up-links
afterNavigate(({ from, to }) => {
const sortChanged = from?.url.searchParams.get('_sort') !== to?.url.searchParams.get('_sort');
if (sortChanged) {
superSearch?.fetchData();
}
});

const hasCharBefore = $derived(/\S/.test(q.charAt(cursor - 1)));
const hasCharAfter = $derived(/\S/.test(q.charAt(cursor)));

Expand Down Expand Up @@ -484,6 +493,7 @@
const searchParams = new SvelteURLSearchParams({
_q: query,
_limit: '5',
_sort: currentSort,
cursor: cursor.toString()
});
if (page.url.searchParams.get('_r')) {
Expand Down
12 changes: 7 additions & 5 deletions lxl-web/src/routes/(app)/[[lang=lang]]/find/+layout.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ export const load = async ({ url, params, fetch, locals, isDataRequest }) => {
const searchParams = new URLSearchParams();

// reruns on change in these params:
const _q = url.searchParams.get('_q');
const _r = url.searchParams.get('_r');
const holdingsParam = url.searchParams.get('holdings');
const reactiveParams = ['_q', '_r', '_sort'];
reactiveParams.forEach((param) => {
if (url.searchParams.has(param) || param === '_q') {
searchParams.set(param, url.searchParams.get(param) || '');
}
});

searchParams.set('_q', _q || '');
if (_r) searchParams.set('_r', _r);
const holdingsParam = url.searchParams.get('holdings');

async function getHoldings(fnurgel: string): Promise<HoldingsData> {
const res = await fetch(`/api/${locale}/${fnurgel}/holdings`);
Expand Down
9 changes: 9 additions & 0 deletions lxl-web/tests/find.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ test('sorting changes the sort param', async ({ page }) => {
await expect(page).toHaveURL(/_sort=_sortKeyByLang.sv/);
});

test('change sort -> facets are updated with new sorting', async ({ page }) => {
await page.getByTestId('facets').getByText('Facklitteratur', { exact: true }).click();
const link = page.getByTestId('facets').getByRole('link', { name: 'Allt inom facklitteratur' });
await expect(link).not.toHaveAttribute('href', /_sortKeyByLang\.sv/);
await page.getByTestId('sort-select').locator('select').selectOption('_sortKeyByLang.sv');
await page.waitForLoadState('networkidle');
await expect(link).toHaveAttribute('href', /_sortKeyByLang\.sv/);
});

test('has pagination', async ({ page }) => {
await expect(page.getByTestId('pagination')).toBeVisible();
});
Expand Down
13 changes: 13 additions & 0 deletions lxl-web/tests/supersearch-lxlweb.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,16 @@ test('shallow routing enables controlling expanded state using the history API',
await page.goForward();
await expect(page.getByRole('dialog')).toBeVisible();
});

test('qualifier remove buttons are updated when sorting change', async ({ page }) => {
await page.goto(
'/find?_q=workCategory%3A"saogf%3AFacklitteratur"+&_limit=20&_offset=0&_sort=&_spell=true'
);
const qualifierRemove = await page
.getByTestId('supersearch')
.getByRole('link', { name: 'ta bort filter Kategori' });
await expect(qualifierRemove).not.toHaveAttribute('href', /_sort=_sortKeyByLang\.sv/);
await page.getByTestId('sort-select').locator('select').selectOption('_sortKeyByLang.sv');
await page.waitForLoadState('networkidle');
await expect(qualifierRemove).toHaveAttribute('href', /_sort=_sortKeyByLang\.sv/);
});
Loading