(search)(terms) add search for terms

This commit is contained in:
Valentyne Stigloher 2024-12-17 20:29:53 +01:00
parent ce682f75f9
commit 0257c55081
4 changed files with 104 additions and 1 deletions

View File

@ -0,0 +1,29 @@
<script setup lang="ts">
import type { SearchResultTerm } from '~/server/api/search.get.ts';
defineProps<{
result: SearchResultTerm;
}>();
</script>
<template>
<nuxt-link :to="result.url" class="text-dark">
<div class="h3">
<Icon v="flag" />
<Spelling :text="result.title" />
</div>
<div class="d-flex">
<div class="col-2">
<img
v-if="result.image"
:src="result.image"
class="w-100 pe-2"
loading="lazy"
>
</div>
<div class="col">
<Spelling :text="result.content" />
</div>
</div>
</nuxt-link>
</template>

View File

@ -38,6 +38,7 @@ const searchInput = useTemplateRef('searchInput');
<SearchItemLink v-else-if="result.type === 'link'" :result="result" />
<SearchItemFaq v-else-if="result.type === 'faq'" :result="result" />
<SearchItemBlog v-else-if="result.type === 'blog'" :result="result" />
<SearchItemTerm v-else-if="result.type === 'term'" :result="result" />
</li>
</ul>
</section>

View File

@ -9,6 +9,7 @@ import type { Config } from '~/locale/config.ts';
import { getPosts, type PostMetadata } from '~/server/blog.ts';
import { getNounEntries } from '~/server/express/nouns.ts';
import { getSourcesEntries } from '~/server/express/sources.ts';
import { getTermsEntries } from '~/server/express/terms.ts';
import { loadSuml, loadSumlFromBase } from '~/server/loader.ts';
import { rootDir } from '~/server/paths.ts';
import { parsePronouns } from '~/src/buildPronoun.ts';
@ -430,6 +431,77 @@ class SearchIndexBlog extends SearchIndex<SearchDocumentBlog, SearchResultBlog>
}
}
interface SearchDocumentTerm {
id: number;
type: SearchIndexTerm['TYPE'];
url: string;
title: string;
image: string | undefined;
content: string;
}
export type SearchResultTerm = SearchDocumentTerm;
class SearchIndexTerm extends SearchIndex<SearchDocumentTerm, SearchResultTerm> {
TYPE = 'term' as const;
constructor() {
super(['url', 'title', 'content']);
}
async getDocuments(config: Config): Promise<SearchDocumentTerm[]> {
if (!config.terminology.enabled) {
return [];
}
const runtimeConfig = useRuntimeConfig();
const base = encodeURIComponent(config.terminology.route);
const db = useDatabase();
const terms = await getTermsEntries(db, () => false);
return terms.map((term, id): SearchDocumentTerm => {
const title = term.term.replaceAll('|', ', ');
let content = '';
if (term.original) {
content += `${clearLinkedText(term.original.replaceAll('|', ';'), false)}`;
}
content += ` ${clearLinkedText(term.definition, false)}`;
let image = undefined;
const flags = JSON.parse(term.flags);
if (flags.length > 0) {
image = `/flags/${flags[0]}.png`;
} else if (term.images) {
image = buildImageUrl(runtimeConfig.public.cloudfront, term.images.split(',')[0], 'flag');
}
return {
id,
type: this.TYPE,
url: `/${base}?filter=${term.key}`,
title,
image,
content,
};
});
}
override transform(result: SearchResult): SearchResultTerm {
const document = this.documents[result.id];
const termsByField = getTermsByField(result.match);
return {
id: document.id,
type: document.type,
url: document.url,
title: highlightMatches(document.title, termsByField.title),
image: document.image,
content: highlightMatches(document.content, termsByField.content, true),
};
}
}
export default defineEventHandler(async (event) => {
const indices = Object.fromEntries(
[
@ -439,6 +511,7 @@ export default defineEventHandler(async (event) => {
new SearchIndexLink(),
new SearchIndexFaq(),
new SearchIndexBlog(),
new SearchIndexTerm(),
].map((index) => [index.TYPE, index]),
);
await Promise.all(Object.values(indices).map((index) => index.init(config)));

View File

@ -71,7 +71,7 @@ const linkOtherVersions = async (db: Database, isGranted: Request['isGranted'],
const router = Router();
const getTermsEntries = defineCachedFunction(async (db: Database, isGranted: Request['isGranted']) => {
export const getTermsEntries = defineCachedFunction(async (db: Database, isGranted: Request['isGranted']) => {
return await linkOtherVersions(
db,
isGranted,