Add genre column to entries

Include genre data in entry search results and show it
in the entries table layout.

Signed-off-by: codex@lucy.xalior.com
This commit is contained in:
2026-01-10 21:53:31 +00:00
parent 5130a72641
commit 84dee2710c
2 changed files with 212 additions and 103 deletions

View File

@@ -10,6 +10,8 @@ type Item = {
id: number; id: number;
title: string; title: string;
isXrated: number; isXrated: number;
genreId: number | null;
genreName?: string | null;
machinetypeId: number | null; machinetypeId: number | null;
machinetypeName?: string | null; machinetypeName?: string | null;
languageId: string | null; languageId: string | null;
@@ -78,6 +80,25 @@ export default function EntriesExplorer({
const pageSize = 20; const pageSize = 20;
const totalPages = useMemo(() => (data ? Math.max(1, Math.ceil(data.total / data.pageSize)) : 1), [data]); const totalPages = useMemo(() => (data ? Math.max(1, Math.ceil(data.total / data.pageSize)) : 1), [data]);
const activeFilters = useMemo(() => {
const chips: string[] = [];
if (q) chips.push(`q: ${q}`);
if (genreId !== "") {
const name = genres.find((g) => g.id === Number(genreId))?.name ?? `#${genreId}`;
chips.push(`genre: ${name}`);
}
if (languageId !== "") {
const name = languages.find((l) => l.id === languageId)?.name ?? languageId;
chips.push(`lang: ${name}`);
}
if (machinetypeId !== "") {
const name = machines.find((m) => m.id === Number(machinetypeId))?.name ?? `#${machinetypeId}`;
chips.push(`machine: ${name}`);
}
if (scope === "title_aliases") chips.push("scope: titles + aliases");
if (scope === "title_aliases_origins") chips.push("scope: titles + aliases + origins");
return chips;
}, [q, genreId, languageId, machinetypeId, scope, genres, languages, machines]);
function updateUrl(nextPage = page) { function updateUrl(nextPage = page) {
const params = new URLSearchParams(); const params = new URLSearchParams();
@@ -176,6 +197,16 @@ export default function EntriesExplorer({
fetchData(q, 1, true); fetchData(q, 1, true);
} }
function resetFilters() {
setQ("");
setGenreId("");
setLanguageId("");
setMachinetypeId("");
setSort("id_desc");
setScope("title");
setPage(1);
}
const prevHref = useMemo(() => { const prevHref = useMemo(() => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (q) params.set("q", q); if (q) params.set("q", q);
@@ -209,9 +240,32 @@ export default function EntriesExplorer({
]} ]}
/> />
<h1 className="mb-3">Entries</h1> <div className="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
<form className="row gy-2 gx-2 align-items-center" onSubmit={onSubmit}> <div>
<div className="col-sm-8 col-md-6 col-lg-4"> <h1 className="mb-1">Entries</h1>
<div className="text-secondary">
{data ? `${data.total.toLocaleString()} results` : "Loading results..."}
</div>
</div>
{activeFilters.length > 0 && (
<div className="d-flex flex-wrap gap-2 align-items-center">
{activeFilters.map((chip) => (
<span key={chip} className="badge text-bg-light">{chip}</span>
))}
<button type="button" className="btn btn-sm btn-outline-secondary" onClick={resetFilters}>
Clear filters
</button>
</div>
)}
</div>
<div className="row g-3">
<div className="col-lg-3">
<div className="card shadow-sm">
<div className="card-body">
<form className="d-flex flex-column gap-2" onSubmit={onSubmit}>
<div>
<label className="form-label small text-secondary">Search</label>
<input <input
type="text" type="text"
className="form-control" className="form-control"
@@ -220,55 +274,55 @@ export default function EntriesExplorer({
onChange={(e) => setQ(e.target.value)} onChange={(e) => setQ(e.target.value)}
/> />
</div> </div>
<div className="col-auto"> <div className="d-grid">
<button className="btn btn-primary" type="submit" disabled={loading}>Search</button> <button className="btn btn-primary" type="submit" disabled={loading}>Search</button>
</div> </div>
<div className="col-auto"> <div>
<label className="form-label small text-secondary">Genre</label>
<select className="form-select" value={genreId} onChange={(e) => { setGenreId(e.target.value === "" ? "" : Number(e.target.value)); setPage(1); }}> <select className="form-select" value={genreId} onChange={(e) => { setGenreId(e.target.value === "" ? "" : Number(e.target.value)); setPage(1); }}>
<option value="">Genre</option> <option value="">All genres</option>
{genres.map((g) => ( {genres.map((g) => (
<option key={g.id} value={g.id}>{g.name}</option> <option key={g.id} value={g.id}>{g.name}</option>
))} ))}
</select> </select>
</div> </div>
<div className="col-auto"> <div>
<label className="form-label small text-secondary">Language</label>
<select className="form-select" value={languageId} onChange={(e) => { setLanguageId(e.target.value); setPage(1); }}> <select className="form-select" value={languageId} onChange={(e) => { setLanguageId(e.target.value); setPage(1); }}>
<option value="">Language</option> <option value="">All languages</option>
{languages.map((l) => ( {languages.map((l) => (
<option key={l.id} value={l.id}>{l.name}</option> <option key={l.id} value={l.id}>{l.name}</option>
))} ))}
</select> </select>
</div> </div>
<div className="col-auto"> <div>
<label className="form-label small text-secondary">Machine</label>
<select className="form-select" value={machinetypeId} onChange={(e) => { setMachinetypeId(e.target.value === "" ? "" : Number(e.target.value)); setPage(1); }}> <select className="form-select" value={machinetypeId} onChange={(e) => { setMachinetypeId(e.target.value === "" ? "" : Number(e.target.value)); setPage(1); }}>
<option value="">Machine</option> <option value="">All machines</option>
{machines.map((m) => ( {machines.map((m) => (
<option key={m.id} value={m.id}>{m.name}</option> <option key={m.id} value={m.id}>{m.name}</option>
))} ))}
</select> </select>
</div> </div>
<div className="col-auto"> <div>
<label className="form-label small text-secondary">Sort</label>
<select className="form-select" value={sort} onChange={(e) => { setSort(e.target.value as "title" | "id_desc"); setPage(1); }}> <select className="form-select" value={sort} onChange={(e) => { setSort(e.target.value as "title" | "id_desc"); setPage(1); }}>
<option value="title">Sort: Title</option> <option value="title">Title (AZ)</option>
<option value="id_desc">Sort: Newest</option> <option value="id_desc">Newest</option>
</select> </select>
</div> </div>
<div className="col-auto"> <div>
<label className="form-label small text-secondary">Search scope</label>
<select className="form-select" value={scope} onChange={(e) => { setScope(e.target.value as SearchScope); setPage(1); }}> <select className="form-select" value={scope} onChange={(e) => { setScope(e.target.value as SearchScope); setPage(1); }}>
<option value="title">Search: Titles</option> <option value="title">Titles</option>
<option value="title_aliases">Search: Titles + Aliases</option> <option value="title_aliases">Titles + Aliases</option>
<option value="title_aliases_origins">Search: Titles + Aliases + Origins</option> <option value="title_aliases_origins">Titles + Aliases + Origins</option>
</select> </select>
</div> </div>
{loading && (
<div className="col-auto text-secondary">Loading...</div>
)}
</form>
{facets && ( {facets && (
<div className="mt-3"> <div>
<div className="d-flex flex-wrap gap-2 align-items-center"> <div className="text-secondary small mb-1">Facets</div>
<span className="text-secondary small">Facets</span> <div className="d-flex flex-wrap gap-2">
<button <button
type="button" type="button"
className={`btn btn-sm ${scope === "title_aliases" ? "btn-primary" : "btn-outline-secondary"}`} className={`btn btn-sm ${scope === "title_aliases" ? "btn-primary" : "btn-outline-secondary"}`}
@@ -290,8 +344,13 @@ export default function EntriesExplorer({
</div> </div>
</div> </div>
)} )}
{loading && <div className="text-secondary small">Loading...</div>}
</form>
</div>
</div>
</div>
<div className="mt-3"> <div className="col-lg-9">
{data && data.items.length === 0 && !loading && ( {data && data.items.length === 0 && !loading && (
<div className="alert alert-warning">No results.</div> <div className="alert alert-warning">No results.</div>
)} )}
@@ -302,6 +361,7 @@ export default function EntriesExplorer({
<tr> <tr>
<th style={{ width: 80 }}>ID</th> <th style={{ width: 80 }}>ID</th>
<th>Title</th> <th>Title</th>
<th style={{ width: 160 }}>Genre</th>
<th style={{ width: 160 }}>Machine</th> <th style={{ width: 160 }}>Machine</th>
<th style={{ width: 120 }}>Language</th> <th style={{ width: 120 }}>Language</th>
</tr> </tr>
@@ -310,8 +370,17 @@ export default function EntriesExplorer({
{data.items.map((it) => ( {data.items.map((it) => (
<tr key={it.id}> <tr key={it.id}>
<td><EntryLink id={it.id} /></td> <td><EntryLink id={it.id} /></td>
<td><EntryLink id={it.id} title={it.title} /></td>
<td> <td>
<EntryLink id={it.id} title={it.title} /> {it.genreId != null ? (
it.genreName ? (
<Link href={`/zxdb/genres/${it.genreId}`}>{it.genreName}</Link>
) : (
<span>{it.genreId}</span>
)
) : (
<span className="text-secondary">-</span>
)}
</td> </td>
<td> <td>
{it.machinetypeId != null ? ( {it.machinetypeId != null ? (
@@ -342,11 +411,10 @@ export default function EntriesExplorer({
</div> </div>
)} )}
</div> </div>
</div>
<div className="d-flex align-items-center gap-2 mt-2"> <div className="d-flex align-items-center gap-2 mt-4">
<span> <span>Page {data?.page ?? 1} / {totalPages}</span>
Page {data?.page ?? 1} / {totalPages}
</span>
<div className="ms-auto d-flex gap-2"> <div className="ms-auto d-flex gap-2">
<Link <Link
className={`btn btn-outline-secondary ${!data || (data.page <= 1) ? "disabled" : ""}`} className={`btn btn-outline-secondary ${!data || (data.page <= 1) ? "disabled" : ""}`}

View File

@@ -74,6 +74,8 @@ export interface SearchResultItem {
id: number; id: number;
title: string; title: string;
isXrated: number; isXrated: number;
genreId: number | null;
genreName?: string | null;
machinetypeId: number | null; machinetypeId: number | null;
machinetypeName?: string | null; machinetypeName?: string | null;
languageId: string | null; languageId: string | null;
@@ -199,12 +201,15 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(whereExpr ?? sql`true`) .where(whereExpr ?? sql`true`)
@@ -239,12 +244,15 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(sql`${entries.id} in (select entry_id from (${union}) as matches)`) .where(sql`${entries.id} in (select entry_id from (${union}) as matches)`)
@@ -273,6 +281,8 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
@@ -280,6 +290,7 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
}) })
.from(searchByTitles) .from(searchByTitles)
.innerJoin(entries, eq(entries.id, searchByTitles.entryId)) .innerJoin(entries, eq(entries.id, searchByTitles.entryId))
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(like(searchByTitles.entryTitle, pattern)) .where(like(searchByTitles.entryTitle, pattern))
@@ -1170,6 +1181,8 @@ export async function getLabelAuthoredEntries(labelId: number, params: LabelCont
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
@@ -1177,6 +1190,7 @@ export async function getLabelAuthoredEntries(labelId: number, params: LabelCont
}) })
.from(authors) .from(authors)
.innerJoin(entries, eq(entries.id, authors.entryId)) .innerJoin(entries, eq(entries.id, authors.entryId))
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(eq(authors.labelId, labelId)) .where(eq(authors.labelId, labelId))
@@ -1200,6 +1214,8 @@ export async function getLabelAuthoredEntries(labelId: number, params: LabelCont
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
@@ -1207,6 +1223,7 @@ export async function getLabelAuthoredEntries(labelId: number, params: LabelCont
}) })
.from(authors) .from(authors)
.innerJoin(entries, eq(entries.id, authors.entryId)) .innerJoin(entries, eq(entries.id, authors.entryId))
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(and(eq(authors.labelId, labelId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`)) .where(and(eq(authors.labelId, labelId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`))
@@ -1236,6 +1253,8 @@ export async function getLabelPublishedEntries(labelId: number, params: LabelCon
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
@@ -1243,6 +1262,7 @@ export async function getLabelPublishedEntries(labelId: number, params: LabelCon
}) })
.from(publishers) .from(publishers)
.innerJoin(entries, eq(entries.id, publishers.entryId)) .innerJoin(entries, eq(entries.id, publishers.entryId))
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(eq(publishers.labelId, labelId)) .where(eq(publishers.labelId, labelId))
@@ -1266,6 +1286,8 @@ export async function getLabelPublishedEntries(labelId: number, params: LabelCon
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
@@ -1273,6 +1295,7 @@ export async function getLabelPublishedEntries(labelId: number, params: LabelCon
}) })
.from(publishers) .from(publishers)
.innerJoin(entries, eq(entries.id, publishers.entryId)) .innerJoin(entries, eq(entries.id, publishers.entryId))
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(and(eq(publishers.labelId, labelId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`)) .where(and(eq(publishers.labelId, labelId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`))
@@ -1409,12 +1432,15 @@ export async function entriesByGenre(
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(eq(entries.genretypeId, genreId)) .where(eq(entries.genretypeId, genreId))
@@ -1435,12 +1461,15 @@ export async function entriesByGenre(
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(and(eq(entries.genretypeId, genreId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`)) .where(and(eq(entries.genretypeId, genreId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`))
@@ -1470,12 +1499,15 @@ export async function entriesByLanguage(
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(eq(entries.languageId, langId)) .where(eq(entries.languageId, langId))
@@ -1496,12 +1528,15 @@ export async function entriesByLanguage(
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(and(eq(entries.languageId, langId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`)) .where(and(eq(entries.languageId, langId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`))
@@ -1531,12 +1566,15 @@ export async function entriesByMachinetype(
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(eq(entries.machinetypeId, mtId)) .where(eq(entries.machinetypeId, mtId))
@@ -1557,12 +1595,15 @@ export async function entriesByMachinetype(
id: entries.id, id: entries.id,
title: entries.title, title: entries.title,
isXrated: entries.isXrated, isXrated: entries.isXrated,
genreId: entries.genretypeId,
genreName: genretypes.name,
machinetypeId: entries.machinetypeId, machinetypeId: entries.machinetypeId,
machinetypeName: machinetypes.name, machinetypeName: machinetypes.name,
languageId: entries.languageId, languageId: entries.languageId,
languageName: languages.name, languageName: languages.name,
}) })
.from(entries) .from(entries)
.leftJoin(genretypes, eq(genretypes.id, entries.genretypeId))
.leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId)) .leftJoin(machinetypes, eq(machinetypes.id, entries.machinetypeId))
.leftJoin(languages, eq(languages.id, entries.languageId)) .leftJoin(languages, eq(languages.id, entries.languageId))
.where(and(eq(entries.machinetypeId, mtId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`)) .where(and(eq(entries.machinetypeId, mtId), sql`${entries.id} in (select entry_id from ${searchByTitles} where ${searchByTitles.entryTitle} like ${pattern})`))