mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-24 05:05:20 -04:00
(search)(inclusive) add search for inclusive
This commit is contained in:
parent
0257c55081
commit
a12b14256d
17
components/search/SearchItemInclusive.vue
Normal file
17
components/search/SearchItemInclusive.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import type { SearchResultInclusive } from '~/server/api/search.get.ts';
|
||||
|
||||
defineProps<{
|
||||
result: SearchResultInclusive;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nuxt-link :to="result.url" class="text-dark">
|
||||
<div class="h3">
|
||||
<Icon v="book-heart" />
|
||||
<Spelling :text="result.title" />
|
||||
</div>
|
||||
<Spelling :text="result.content" />
|
||||
</nuxt-link>
|
||||
</template>
|
@ -39,6 +39,7 @@ const searchInput = useTemplateRef('searchInput');
|
||||
<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" />
|
||||
<SearchItemInclusive v-else-if="result.type === 'inclusive'" :result="result" />
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
@ -7,6 +7,7 @@ import type { MatchInfo, SearchResult } from 'minisearch';
|
||||
|
||||
import type { Config } from '~/locale/config.ts';
|
||||
import { getPosts, type PostMetadata } from '~/server/blog.ts';
|
||||
import { getInclusiveEntries } from '~/server/express/inclusive.ts';
|
||||
import { getNounEntries } from '~/server/express/nouns.ts';
|
||||
import { getSourcesEntries } from '~/server/express/sources.ts';
|
||||
import { getTermsEntries } from '~/server/express/terms.ts';
|
||||
@ -502,6 +503,65 @@ class SearchIndexTerm extends SearchIndex<SearchDocumentTerm, SearchResultTerm>
|
||||
}
|
||||
}
|
||||
|
||||
interface SearchDocumentInclusive {
|
||||
id: number;
|
||||
type: SearchIndexInclusive['TYPE'];
|
||||
url: string;
|
||||
title: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export type SearchResultInclusive = SearchDocumentInclusive;
|
||||
|
||||
class SearchIndexInclusive extends SearchIndex<SearchDocumentInclusive, SearchResultInclusive> {
|
||||
TYPE = 'inclusive' as const;
|
||||
|
||||
constructor() {
|
||||
super(['url', 'title', 'content']);
|
||||
}
|
||||
|
||||
async getDocuments(config: Config): Promise<SearchDocumentInclusive[]> {
|
||||
if (!config.inclusive.enabled) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const base = encodeURIComponent(config.inclusive.route);
|
||||
|
||||
const db = useDatabase();
|
||||
const inclusiveEntries = await getInclusiveEntries(db, () => false);
|
||||
return inclusiveEntries.map((inclusiveEntry, id): SearchDocumentInclusive => {
|
||||
const insteadOf = inclusiveEntry.insteadOf.split('|');
|
||||
const say = inclusiveEntry.say?.split('|') ?? [];
|
||||
let content = `${translator.translate('inclusive.insteadOf')}: ${insteadOf.join(', ')}` +
|
||||
` – ${translator.translate('inclusive.say')}: ${say.join(', ')}`;
|
||||
if (inclusiveEntry.clarification) {
|
||||
content += `; ${inclusiveEntry.clarification}`;
|
||||
}
|
||||
content += `; ${inclusiveEntry.because}`;
|
||||
|
||||
return {
|
||||
id,
|
||||
type: this.TYPE,
|
||||
url: `/${base}?filter=${insteadOf[0]}`,
|
||||
title: `${insteadOf[0]} – ${say[0]}`,
|
||||
content,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
override transform(result: SearchResult): SearchResultInclusive {
|
||||
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),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const indices = Object.fromEntries(
|
||||
[
|
||||
@ -512,6 +572,7 @@ export default defineEventHandler(async (event) => {
|
||||
new SearchIndexFaq(),
|
||||
new SearchIndexBlog(),
|
||||
new SearchIndexTerm(),
|
||||
new SearchIndexInclusive(),
|
||||
].map((index) => [index.TYPE, index]),
|
||||
);
|
||||
await Promise.all(Object.values(indices).map((index) => index.init(config)));
|
||||
|
@ -44,7 +44,7 @@ const approve = async (db: Database, id: string) => {
|
||||
|
||||
const router = Router();
|
||||
|
||||
const getInclusiveEntries = defineCachedFunction(async (db: Database, isGranted: Request['isGranted']) => {
|
||||
export const getInclusiveEntries = defineCachedFunction(async (db: Database, isGranted: Request['isGranted']) => {
|
||||
return sortClearedLinkedText(await db.all<InclusiveRowWithAuthor>(SQL`
|
||||
SELECT i.*, u.username AS author FROM inclusive i
|
||||
LEFT JOIN users u ON i.author_id = u.id
|
||||
|
Loading…
x
Reference in New Issue
Block a user