From 5a0d1f6c19a1277e8278e88baac0d76ab912d934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 09:39:31 +0100 Subject: [PATCH 01/14] Format data for suggest asResult --- lxl-web/src/lib/utils/search.ts | 2 +- .../(app)/[[lang=lang]]/find/+page.server.ts | 9 +----- .../api/[[lang=lang]]/supersearch/+server.ts | 29 +++++++++---------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/lxl-web/src/lib/utils/search.ts b/lxl-web/src/lib/utils/search.ts index ff22ae481..ba597ee68 100644 --- a/lxl-web/src/lib/utils/search.ts +++ b/lxl-web/src/lib/utils/search.ts @@ -37,7 +37,7 @@ export async function asResult( vocabUtil: VocabUtil, locale: LangCode, auxdSecret: string, - usePath: string + usePath?: string ): Promise { const translate = await getTranslator(locale); diff --git a/lxl-web/src/routes/(app)/[[lang=lang]]/find/+page.server.ts b/lxl-web/src/routes/(app)/[[lang=lang]]/find/+page.server.ts index d9a542bbc..8cdb476fb 100644 --- a/lxl-web/src/routes/(app)/[[lang=lang]]/find/+page.server.ts +++ b/lxl-web/src/routes/(app)/[[lang=lang]]/find/+page.server.ts @@ -43,14 +43,7 @@ export const load = async ({ params, url, locals, fetch }) => { const result = (await recordsRes.json()) as PartialCollectionView; - const searchResult = await asResult( - result, - displayUtil, - vocabUtil, - locale, - env.AUXD_SECRET, - url.pathname - ); + const searchResult = await asResult(result, displayUtil, vocabUtil, locale, env.AUXD_SECRET); return { searchResult, userSettings }; }; diff --git a/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts b/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts index f40b6ea9e..ae9deb8df 100644 --- a/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts +++ b/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts @@ -1,12 +1,9 @@ import { env } from '$env/dynamic/private'; import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types.ts'; -import { LxlLens } from '$lib/types/display'; import { getSupportedLocale } from '$lib/i18n/locales.js'; -import { toString } from '$lib/utils/xl.js'; -import { displayMappings } from '$lib/utils/search.js'; -import { getTranslator } from '$lib/i18n/index.js'; import getEditedPartEntries from './getEditedPartEntries.js'; +import { asResult } from '$lib/utils/search.js'; /** * TODO: @@ -16,8 +13,9 @@ import getEditedPartEntries from './getEditedPartEntries.js'; export const GET: RequestHandler = async ({ url, params, locals }) => { const displayUtil = locals.display; + const vocabUtil = locals.vocab; + const locale = getSupportedLocale(params?.lang); - const translate = await getTranslator(locale); const _q = url.searchParams.get('_q'); const cursor = parseInt(url.searchParams.get('cursor') || '0', 10); @@ -31,6 +29,13 @@ export const GET: RequestHandler = async ({ url, params, locals }) => { newSearchParams.set(key, value); }); newSearchParams.delete('cursor'); + + if (!_q.toString().includes('"rdf:type":') && !_q.toString().includes('"rdf:type"=')) { + // Add types to suggest + const types = + '"rdf:type":(Agent OR Concept OR Language OR Work) "rdf:type":(NOT ComplexSubject) '; + newSearchParams.set('_q', types + _q.toString()); + } console.log('Initial search params:', decodeURIComponent(url.searchParams.toString())); console.log('Search params sent to /find:', decodeURIComponent(newSearchParams.toString())); } @@ -38,17 +43,11 @@ export const GET: RequestHandler = async ({ url, params, locals }) => { const findResponse = await fetch(`${env.API_URL}/find?${newSearchParams.toString()}`); const data = await findResponse.json(); + const searchResult = await asResult(data, displayUtil, vocabUtil, locale, env.AUXD_SECRET); + return json({ '@id': data['@id'], - items: data.items?.map((item) => ({ - '@id': item['@id'], - '@type': item['@type'], - heading: toString(displayUtil.lensAndFormat(item, LxlLens.CardHeading, locale)) - })), - ...(data?.search?.mapping && { - mapping: displayMappings(data, displayUtil, locale, translate) - }), - totalItems: data.totalItems, - '@context': data['@context'] + '@context': data['@context'], + ...searchResult }); }; From b0628759db0bfb0644a775859e7e426fe2551fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 09:41:29 +0100 Subject: [PATCH 02/14] Upgrade Svelte --- lxl-web/package.json | 2 +- package-lock.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lxl-web/package.json b/lxl-web/package.json index f96d96f56..f6686686a 100644 --- a/lxl-web/package.json +++ b/lxl-web/package.json @@ -47,7 +47,7 @@ "prettier-plugin-svelte": "^3.2.6", "prettier-plugin-tailwindcss": "^0.6.6", "supersearch": "^0.0.1", - "svelte": "^5.1.9", + "svelte": "^5.18.0", "svelte-check": "^4.0.4", "tailwindcss": "^3.4.10", "tslib": "^2.6.3", diff --git a/package-lock.json b/package-lock.json index 0e1ca5818..23405e161 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "prettier-plugin-svelte": "^3.2.6", "prettier-plugin-tailwindcss": "^0.6.6", "supersearch": "^0.0.1", - "svelte": "^5.1.9", + "svelte": "^5.18.0", "svelte-check": "^4.0.4", "tailwindcss": "^3.4.10", "tslib": "^2.6.3", From 2e411902aa4aa7d01d2532745fa30e5608dc42b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 10:04:48 +0100 Subject: [PATCH 03/14] Add SuggestionCard --- .../src/lib/components/SuggestionCard.svelte | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 lxl-web/src/lib/components/SuggestionCard.svelte diff --git a/lxl-web/src/lib/components/SuggestionCard.svelte b/lxl-web/src/lib/components/SuggestionCard.svelte new file mode 100644 index 000000000..aafbaad5e --- /dev/null +++ b/lxl-web/src/lib/components/SuggestionCard.svelte @@ -0,0 +1,248 @@ + + +
+
+ +
+
+ {#if item.image} + {$page.data.t('general.latestInstanceCover')} + {#if item['@type'] !== 'Text' && item['@type'] !== 'Person' && getTypeIcon(item['@type'])} + {@const SvelteComponent = getTypeIcon(item['@type'])} +
+
+ +
+
+ {/if} + {:else} +
+ + {#if getTypeIcon(item['@type'])} + {@const SvelteComponent_1 = getTypeIcon(item['@type'])} + + {/if} +
+ {/if} +
+
+
+
+
+

+ + + + + {#if item[LxlLens.CardBody]?._display?.[0]?.contribution} +  {'•'}  + + + + {/if} +

+
+ +
+
+ + {item.typeStr} + + {' • '} + {#each item[LensType.WebCardFooter]?._display as obj} + {#if 'hasInstance' in obj} + {' • '} + {@const instances = getInstanceData(obj.hasInstance)} + {#if instances?.years} + + {#if instances.count > 1} + {instances?.count} + {$page.data.t('search.editions')} + {`(${instances.years})`} + {:else} + {instances.years} + {/if} + + {/if} + {:else} + + + + {/if} + {/each} +
+
+ {#if item._debug} + {#key item._debug} + + {#if showDebugExplain} +
+ +
+ {/if} + {/key} + {/if} +
+
+ + From debf9e0afb147d6c6543e964e8cf4874d6b6019c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 10:21:47 +0100 Subject: [PATCH 04/14] Add component to result snippet, fix combobox layout, sticky --- .../lib/components/SuperSearchWrapper.svelte | 49 +++++-------------- lxl-web/tailwind.config.js | 2 +- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/lxl-web/src/lib/components/SuperSearchWrapper.svelte b/lxl-web/src/lib/components/SuperSearchWrapper.svelte index 34568795b..c3ef7cfc0 100644 --- a/lxl-web/src/lib/components/SuperSearchWrapper.svelte +++ b/lxl-web/src/lib/components/SuperSearchWrapper.svelte @@ -2,10 +2,10 @@ import { page } from '$app/stores'; import { afterNavigate } from '$app/navigation'; import { SuperSearch, lxlQualifierPlugin } from 'supersearch'; + import SuggestionCard from './SuggestionCard.svelte'; import addDefaultSearchParams from '$lib/utils/addDefaultSearchParams'; import getSortedSearchParams from '$lib/utils/getSortedSearchParams'; import getLabelFromMappings from '$lib/utils/getLabelsFromMapping.svelte'; - import { relativizeUrl } from '$lib/utils/http'; import type { DisplayMapping } from '$lib/types/search'; import { lxlQuery } from 'codemirror-lang-lxlquery'; import BiXLg from '~icons/bi/x-lg'; @@ -81,7 +81,7 @@ queryFn={(query, cursor) => { return new URLSearchParams({ _q: query, - _limit: '10', + _limit: '8', cursor: cursor.toString() }); }} @@ -128,16 +128,9 @@ {/snippet} {#snippet resultItem(item, getCellId, isFocusedCell)} - + {#if item} + + {/if} {/snippet} {#each searchParams as [name, value]} @@ -149,11 +142,11 @@ From c263a4ee7cf64bb666bdc60a4747cb8696d31562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 13:58:13 +0100 Subject: [PATCH 09/14] Add new class syntax --- lxl-web/src/lib/components/SuggestionCard.svelte | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lxl-web/src/lib/components/SuggestionCard.svelte b/lxl-web/src/lib/components/SuggestionCard.svelte index 2ceba9426..1396e69b2 100644 --- a/lxl-web/src/lib/components/SuggestionCard.svelte +++ b/lxl-web/src/lib/components/SuggestionCard.svelte @@ -73,13 +73,15 @@ width={item.image.widthṔx} height={item.image.heightPx} alt={$page.data.t('general.latestInstanceCover')} - class:rounded-full={item['@type'] === 'Person'} - class="aspect-square object-contain object-top" + class={[ + 'aspect-square object-contain object-top', + item['@type'] === 'Person' && 'rounded-full' + ]} /> {#if item['@type'] !== 'Text' && item['@type'] !== 'Person' && getTypeIcon(item['@type'])} {@const SvelteComponent = getTypeIcon(item['@type'])}
-
+
@@ -89,9 +91,10 @@ {#if getTypeIcon(item['@type'])} {@const SvelteComponent_1 = getTypeIcon(item['@type'])} From ad0ffda67b9c3facf478daac7a9cd0558f71afbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 14:29:36 +0100 Subject: [PATCH 10/14] Extract getInstanceData --- .../src/lib/components/SuggestionCard.svelte | 28 +- .../src/lib/components/find/SearchCard.svelte | 28 +- lxl-web/src/lib/utils/getInstanceData.test.ts | 358 ++++++++++++++++++ lxl-web/src/lib/utils/getInstanceData.ts | 29 ++ 4 files changed, 389 insertions(+), 54 deletions(-) create mode 100644 lxl-web/src/lib/utils/getInstanceData.test.ts create mode 100644 lxl-web/src/lib/utils/getInstanceData.ts diff --git a/lxl-web/src/lib/components/SuggestionCard.svelte b/lxl-web/src/lib/components/SuggestionCard.svelte index 1396e69b2..a60dbaa97 100644 --- a/lxl-web/src/lib/components/SuggestionCard.svelte +++ b/lxl-web/src/lib/components/SuggestionCard.svelte @@ -1,11 +1,10 @@
diff --git a/lxl-web/src/lib/components/find/SearchCard.svelte b/lxl-web/src/lib/components/find/SearchCard.svelte index e9618a2fd..9556d6e45 100644 --- a/lxl-web/src/lib/components/find/SearchCard.svelte +++ b/lxl-web/src/lib/components/find/SearchCard.svelte @@ -1,12 +1,11 @@
diff --git a/lxl-web/src/lib/utils/getInstanceData.test.ts b/lxl-web/src/lib/utils/getInstanceData.test.ts new file mode 100644 index 000000000..143b86c47 --- /dev/null +++ b/lxl-web/src/lib/utils/getInstanceData.test.ts @@ -0,0 +1,358 @@ +import { describe, it, expect } from 'vitest'; +import getInstanceData from './getInstanceData'; + +describe('getInstanceData', () => { + it('returns count and years for multiple instances', () => { + expect(getInstanceData(multipleInstances)).toStrictEqual({ count: 3, years: '2020-2022' }); + }); + + it('returns count and year for one instance', () => { + expect(getInstanceData(oneInstance)).toStrictEqual({ count: 1, years: '2016' }); + }); + + it('can handle an unknown object', () => { + expect(getInstanceData({ foo: 'bar' })).toStrictEqual({ count: 1, years: '' }); + }); +}); + +const multipleInstances = [ + { + '@id': 'https://libris-qa.kb.se/kz701csjh57m5k0z', + '@type': 'Instance', + _display: [ + { + _style: ['block'], + hasTitle: { + '@type': 'Title', + _display: [ + { + mainTitle: 'Häng City', + _label: 'huvudtitel' + } + ], + _label: 'Titel' + }, + _label: 'har titel' + }, + { + _contentBefore: ' • ', + responsibilityStatement: 'Mikael Yvesand', + _label: 'upphovsuppgift' + }, + { + _contentBefore: ' • ', + publication: { + '@type': 'PrimaryPublication', + _display: [ + { + country: { + '@id': 'https://libris-qa.kb.se/jf9xxz4ml0jrz74j', + '@type': 'Country', + _display: [ + { + prefLabel: 'Sverige', + _label: 'föredragen benämning' + } + ], + _label: 'Land' + }, + _label: 'land' + }, + { + _contentBefore: ' • ', + place: { + '@type': 'Place', + _display: [ + { + label: 'Stockholm', + _label: 'benämning' + } + ], + _label: 'Plats' + }, + _label: 'plats' + }, + { + _contentBefore: ' : ', + agent: { + '@type': 'Agent', + _display: [ + { + label: 'Polaris', + _label: 'benämning' + } + ], + _style: ['link'], + _label: 'Agent' + }, + _label: 'agent' + }, + { + _contentBefore: ', ', + year: '2020', + _label: 'år' + }, + { + _contentBefore: ', ', + date: '[2022]', + _label: 'datum' + } + ], + _label: 'Primär utgivning' + }, + _label: 'utgivning' + } + ], + _style: ['link'], + _label: 'Instans' + }, + { + '@id': 'https://libris-qa.kb.se/p3cc9rvhmwp5vnw4', + '@type': 'Electronic', + _display: [ + { + _style: ['block'], + hasTitle: { + '@type': 'Title', + _display: [ + { + mainTitle: 'Häng City', + _label: 'huvudtitel' + } + ], + _label: 'Titel' + }, + _label: 'har titel' + }, + { + _contentBefore: ' • ', + responsibilityStatement: 'Mikael Yvesand', + _label: 'upphovsuppgift' + }, + { + _contentBefore: ' • ', + publication: { + '@type': 'PrimaryPublication', + _display: [ + { + country: { + '@id': 'https://libris-qa.kb.se/jf9xxz4ml0jrz74j', + '@type': 'Country', + _display: [ + { + prefLabel: 'Sverige', + _label: 'föredragen benämning' + } + ], + _label: 'Land' + }, + _label: 'land' + }, + { + _contentBefore: ' : ', + agent: { + '@type': 'Agent', + _display: [ + { + label: 'Bokförlaget Polaris', + _label: 'benämning' + } + ], + _style: ['link'], + _label: 'Agent' + }, + _label: 'agent' + }, + { + _contentBefore: ', ', + year: '2021', + _label: 'år' + } + ], + _label: 'Primär utgivning' + }, + _label: 'utgivning' + } + ], + _style: ['link'], + _contentBefore: ', ', + _label: 'Elektronisk' + }, + { + '@id': 'https://libris-qa.kb.se/br78xdb78kg8gzr5', + '@type': 'Instance', + _display: [ + { + _style: ['block'], + hasTitle: { + '@type': 'Title', + _display: [ + { + mainTitle: 'Häng City', + _label: 'huvudtitel' + } + ], + _label: 'Titel' + }, + _label: 'har titel' + }, + { + _contentBefore: ' • ', + responsibilityStatement: 'Mikael Yvesand', + _label: 'upphovsuppgift' + }, + { + _contentBefore: ' • ', + publication: { + '@type': 'PrimaryPublication', + _display: [ + { + country: { + '@id': 'https://libris-qa.kb.se/jf9xxz4ml0jrz74j', + '@type': 'Country', + _display: [ + { + prefLabel: 'Sverige', + _label: 'föredragen benämning' + } + ], + _label: 'Land' + }, + _label: 'land' + }, + { + _contentBefore: ' • ', + place: { + '@type': 'Place', + _display: [ + { + label: 'Stockholm', + _label: 'benämning' + } + ], + _label: 'Plats' + }, + _label: 'plats' + }, + { + _contentBefore: ' : ', + agent: { + '@type': 'Agent', + _display: [ + { + label: 'Polaris', + _label: 'benämning' + } + ], + _style: ['link'], + _label: 'Agent' + }, + _label: 'agent' + }, + { + _contentBefore: ', ', + year: '2022', + _label: 'år' + }, + { + _contentBefore: ', ', + date: '[2022]', + _label: 'datum' + } + ], + _label: 'Primär utgivning' + }, + _label: 'utgivning' + } + ], + _style: ['link'], + _contentBefore: ', ', + _label: 'Instans' + } +]; + +const oneInstance = { + '@id': 'https://libris-qa.kb.se/5l9h8z9t3f8rs82v#it', + '@type': 'SoundRecording', + _display: [ + { + _style: ['block'], + hasTitle: { + '@type': 'Title', + _display: [ + { + mainTitle: 'Häng City', + _label: 'huvudtitel' + } + ], + _label: 'Titel' + }, + _label: 'har titel' + }, + { + _contentBefore: ' • ', + responsibilityStatement: 'Mikael Yvesand', + _label: 'upphovsuppgift' + }, + { + _contentBefore: ' • ', + publication: { + '@type': 'PrimaryPublication', + _display: [ + { + country: { + '@id': 'https://libris-qa.kb.se/jf9xxz4ml0jrz74j', + '@type': 'Country', + _display: [ + { + prefLabel: 'Sverige', + _label: 'föredragen benämning' + } + ], + _label: 'Land' + }, + _label: 'land' + }, + { + _contentBefore: ' • ', + place: { + '@type': 'Place', + _display: [ + { + label: '[Stockholm]', + _label: 'benämning' + } + ], + _label: 'Plats' + }, + _label: 'plats' + }, + { + _contentBefore: ' : ', + agent: { + '@type': 'Agent', + _display: [ + { + label: 'Polaris', + _label: 'benämning' + } + ], + _style: ['link'], + _label: 'Agent' + }, + _label: 'agent' + }, + { + _contentBefore: ', ', + year: '2016', + _label: 'år' + } + ], + _label: 'Primär utgivning' + }, + _label: 'utgivning' + } + ], + _style: ['link'], + _label: 'Ljudinspelning' +}; diff --git a/lxl-web/src/lib/utils/getInstanceData.ts b/lxl-web/src/lib/utils/getInstanceData.ts new file mode 100644 index 000000000..ab7919059 --- /dev/null +++ b/lxl-web/src/lib/utils/getInstanceData.ts @@ -0,0 +1,29 @@ +import jmespath from 'jmespath'; +import type { ResourceData } from '$lib/types/resourceData'; + +function getInstanceData(instances: ResourceData) { + if (typeof instances === 'object') { + let years: string = ''; + let count = 1; + let query = '_display[].publication[].*[][?year].year[]'; + + if (Array.isArray(instances)) { + count = instances.length; + query = '[]._display[].publication[].*[][?year].year[]'; + } + + const res = jmespath.search(instances, query) as string[] | null; + if (res) { + years = res + .filter((el, i, arr) => !isNaN(parseInt(el)) && arr.indexOf(el) === i) + .sort() + .filter((el, i, arr) => i === 0 || i === arr.length - 1) + .join('-'); + } + + return { count, years }; + } + return null; +} + +export default getInstanceData; From 0688c2342bfd32aa90119d3876eca1d9a391493c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 14:45:30 +0100 Subject: [PATCH 11/14] Implement debug esScore for suggestions --- lxl-web/src/lib/components/SuggestionCard.svelte | 4 ++-- lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lxl-web/src/lib/components/SuggestionCard.svelte b/lxl-web/src/lib/components/SuggestionCard.svelte index a60dbaa97..0c00a145b 100644 --- a/lxl-web/src/lib/components/SuggestionCard.svelte +++ b/lxl-web/src/lib/components/SuggestionCard.svelte @@ -135,7 +135,7 @@ {#key item._debug} {#if showDebugExplain} -
+
{/if} diff --git a/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts b/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts index ae9deb8df..dbda00aa4 100644 --- a/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts +++ b/lxl-web/src/routes/api/[[lang=lang]]/supersearch/+server.ts @@ -4,6 +4,7 @@ import type { RequestHandler } from './$types.ts'; import { getSupportedLocale } from '$lib/i18n/locales.js'; import getEditedPartEntries from './getEditedPartEntries.js'; import { asResult } from '$lib/utils/search.js'; +import { DebugFlags } from '$lib/types/userSettings.js'; /** * TODO: @@ -39,8 +40,9 @@ export const GET: RequestHandler = async ({ url, params, locals }) => { console.log('Initial search params:', decodeURIComponent(url.searchParams.toString())); console.log('Search params sent to /find:', decodeURIComponent(newSearchParams.toString())); } + const debug = locals.userSettings?.debug?.includes(DebugFlags.ES_SCORE) ? '&_debug=esScore' : ''; - const findResponse = await fetch(`${env.API_URL}/find?${newSearchParams.toString()}`); + const findResponse = await fetch(`${env.API_URL}/find?${newSearchParams.toString()}${debug}`); const data = await findResponse.json(); const searchResult = await asResult(data, displayUtil, vocabUtil, locale, env.AUXD_SECRET); From 6140467a7ec1777ee11680d97617e93cf4c3ff68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20Engstr=C3=B6m?= Date: Thu, 30 Jan 2025 17:07:21 +0100 Subject: [PATCH 12/14] Layout fix --- lxl-web/src/routes/(app)/[[lang=lang]]/SiteHeader.svelte | 6 +++--- lxl-web/tailwind.config.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lxl-web/src/routes/(app)/[[lang=lang]]/SiteHeader.svelte b/lxl-web/src/routes/(app)/[[lang=lang]]/SiteHeader.svelte index 71bc314c5..185168fcf 100644 --- a/lxl-web/src/routes/(app)/[[lang=lang]]/SiteHeader.svelte +++ b/lxl-web/src/routes/(app)/[[lang=lang]]/SiteHeader.svelte @@ -20,8 +20,8 @@
-
-