mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-23 20:54:48 -04:00
(search)(nouns) add search for nouns
This commit is contained in:
parent
7b27ed0ba7
commit
09ac9782a1
17
components/search/SearchItemNoun.vue
Normal file
17
components/search/SearchItemNoun.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { SearchResultNoun } from '~/server/api/search.get.ts';
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
result: SearchResultNoun;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<nuxt-link :to="result.url" class="text-dark">
|
||||||
|
<div class="h3">
|
||||||
|
<Icon v="book" />
|
||||||
|
<Spelling :text="result.title" />
|
||||||
|
</div>
|
||||||
|
<Spelling :text="result.content" />
|
||||||
|
</nuxt-link>
|
||||||
|
</template>
|
@ -33,6 +33,7 @@ const searchInput = useTemplateRef('searchInput');
|
|||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li v-for="result of results.data.value" :key="`${result.type}-${result.id}`" class="list-group-item">
|
<li v-for="result of results.data.value" :key="`${result.type}-${result.id}`" class="list-group-item">
|
||||||
<SearchItemPronoun v-if="result.type === 'pronoun'" :result="result" />
|
<SearchItemPronoun v-if="result.type === 'pronoun'" :result="result" />
|
||||||
|
<SearchItemNoun v-else-if="result.type === 'noun'" :result="result" />
|
||||||
<SearchItemBlog v-else-if="result.type === 'blog'" :result="result" />
|
<SearchItemBlog v-else-if="result.type === 'blog'" :result="result" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -7,9 +7,11 @@ import type { MatchInfo, SearchResult } from 'minisearch';
|
|||||||
|
|
||||||
import type { Config } from '~/locale/config.ts';
|
import type { Config } from '~/locale/config.ts';
|
||||||
import { getPosts, type PostMetadata } from '~/server/blog.ts';
|
import { getPosts, type PostMetadata } from '~/server/blog.ts';
|
||||||
|
import { getNounEntries } from '~/server/express/nouns.ts';
|
||||||
import { loadSuml, loadSumlFromBase } from '~/server/loader.ts';
|
import { loadSuml, loadSumlFromBase } from '~/server/loader.ts';
|
||||||
import { rootDir } from '~/server/paths.ts';
|
import { rootDir } from '~/server/paths.ts';
|
||||||
import { parsePronouns } from '~/src/buildPronoun.ts';
|
import { parsePronouns } from '~/src/buildPronoun.ts';
|
||||||
|
import { genders, gendersWithNumerus } from '~/src/classes.ts';
|
||||||
import { clearLinkedText } from '~/src/helpers.ts';
|
import { clearLinkedText } from '~/src/helpers.ts';
|
||||||
import parseMarkdown from '~/src/parseMarkdown.ts';
|
import parseMarkdown from '~/src/parseMarkdown.ts';
|
||||||
import { Translator } from '~/src/translator.ts';
|
import { Translator } from '~/src/translator.ts';
|
||||||
@ -136,6 +138,62 @@ class SearchIndexPronoun extends SearchIndex<SearchDocumentPronoun, SearchResult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SearchDocumentNoun {
|
||||||
|
id: number;
|
||||||
|
type: SearchIndexNoun['TYPE'];
|
||||||
|
url: string;
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SearchResultNoun = SearchDocumentNoun;
|
||||||
|
|
||||||
|
class SearchIndexNoun extends SearchIndex<SearchDocumentNoun, SearchResultNoun> {
|
||||||
|
TYPE = 'noun' as const;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(['url', 'title', 'content']);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDocuments(config: Config): Promise<SearchDocumentNoun[]> {
|
||||||
|
if (!config.nouns.enabled) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const base = encodeURIComponent(config.nouns.route);
|
||||||
|
|
||||||
|
const db = useDatabase();
|
||||||
|
const nouns = await getNounEntries(db, () => false);
|
||||||
|
return nouns.map((noun, id): SearchDocumentNoun => {
|
||||||
|
const firstWords = genders
|
||||||
|
.filter((gender) => noun[gender])
|
||||||
|
.map((gender) => noun[gender].split('|')[0]);
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
type: this.TYPE,
|
||||||
|
url: `/${base}?filter=${firstWords[0]}`,
|
||||||
|
title: firstWords.join(' – '),
|
||||||
|
content: gendersWithNumerus
|
||||||
|
.filter((genderWithNumerus) => noun[genderWithNumerus])
|
||||||
|
.map((genderWithNumerus) => noun[genderWithNumerus].replaceAll('|', ', '))
|
||||||
|
.join(' – '),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
override transform(result: SearchResult): SearchResultNoun {
|
||||||
|
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),
|
||||||
|
content: highlightMatches(document.content, termsByField.content, true),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface SearchDocumentBlog extends PostMetadata {
|
interface SearchDocumentBlog extends PostMetadata {
|
||||||
id: number;
|
id: number;
|
||||||
type: SearchIndexBlog['TYPE'];
|
type: SearchIndexBlog['TYPE'];
|
||||||
@ -201,6 +259,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
const indices = Object.fromEntries(
|
const indices = Object.fromEntries(
|
||||||
[
|
[
|
||||||
new SearchIndexPronoun(),
|
new SearchIndexPronoun(),
|
||||||
|
new SearchIndexNoun(),
|
||||||
new SearchIndexBlog(),
|
new SearchIndexBlog(),
|
||||||
].map((index) => [index.TYPE, index]),
|
].map((index) => [index.TYPE, index]),
|
||||||
);
|
);
|
||||||
|
@ -99,7 +99,7 @@ const selectFragment = (sourcesMap: Record<string, SourceRow>, keyAndFragment: s
|
|||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const getNounEntries = defineCachedFunction(async (db: Database, isGranted: Request['isGranted']) => {
|
export const getNounEntries = defineCachedFunction(async (db: Database, isGranted: Request['isGranted']) => {
|
||||||
return await addVersions(db, isGranted, await db.all<NounRowWithAuthor>(SQL`
|
return await addVersions(db, isGranted, await db.all<NounRowWithAuthor>(SQL`
|
||||||
SELECT n.*, u.username AS author FROM nouns n
|
SELECT n.*, u.username AS author FROM nouns n
|
||||||
LEFT JOIN users u ON n.author_id = u.id
|
LEFT JOIN users u ON n.author_id = u.id
|
||||||
|
Loading…
x
Reference in New Issue
Block a user