presentation/views/search.view.ts

presentation/views/search.view.ts is a file in Bane's Lab Site. 40 lines of code and 6 definitions.

import { SEARCH_DESCRIPTION, SEARCH_TITLE } from "#configuration/strings/page.strings";
import { SEARCH_EMPTY_SECTIONS, SEARCH_META, SEARCH_SECTIONS } from "#configuration/strings/search.strings";
import { SEARCH_MIN_QUERY_LENGTH, SEARCH_QUERY_PARAM } from "#configuration/constants/search.constants";
import { appendChildren, createElement } from "#core/factories/element.factory";
import type { PageDefinition } from "#types/page.types";
import { SEARCH_PAGE } from "#core/ids/page.ids";
import { isStaticRender } from "#core/predicates/document.predicate";
import { loadCorpus } from "#domain/loaders/search.loader";
import { queryValue } from "#core/assets/link.assets";
import { renderDocument } from "#presentation/renderers/document.renderer";
import { renderSpread } from "#presentation/renderers/search.renderer";
import { renderTabHeader } from "#presentation/renderers/tab.renderer";
import { searchSpreads } from "#domain/converters/search.converter";

const fillResults = async function fillResults(holder: Element, query: string): Promise<void> {
    const spreads = searchSpreads(await loadCorpus(), query);
    if (spreads.length === 0) {
        holder.replaceChildren(renderDocument(SEARCH_META, SEARCH_EMPTY_SECTIONS));
        return;
    }
    appendChildren(holder, spreads.map(renderSpread));
};

const renderSearch = function renderSearch(): Element {
    const query = queryValue(window.location.search, SEARCH_QUERY_PARAM).trim();
    if (isStaticRender() || query.length < SEARCH_MIN_QUERY_LENGTH) {
        return renderDocument(SEARCH_META, SEARCH_SECTIONS);
    }
    const holder = createElement("div", {
        children: [renderTabHeader({ subtitle: query, title: SEARCH_TITLE, version: SEARCH_META.version })],
        className: "tab-page-content",
    });
    void fillResults(holder, query);
    return holder;
};

export const PAGE: PageDefinition = {
    content: { kind: "document", meta: SEARCH_META, sections: SEARCH_SECTIONS },
    description: SEARCH_DESCRIPTION,
    id: SEARCH_PAGE,
    render: renderSearch,
    title: SEARCH_TITLE,
};