Add multi-select machine filters
Replace machine dropdowns with multi-select chips and pass machine lists in queries. Signed-off-by: codex@lucy.xalior.com
This commit is contained in:
@@ -63,7 +63,7 @@ export interface SearchParams {
|
||||
// Optional simple filters (ANDed together)
|
||||
genreId?: number;
|
||||
languageId?: string;
|
||||
machinetypeId?: number;
|
||||
machinetypeId?: number | number[];
|
||||
// Sorting
|
||||
sort?: "title" | "id_desc";
|
||||
// Search scope (defaults to titles only)
|
||||
@@ -177,7 +177,10 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
|
||||
const offset = (page - 1) * pageSize;
|
||||
const sort = params.sort ?? (q ? "title" : "id_desc");
|
||||
const scope: EntrySearchScope = params.scope ?? "title";
|
||||
const preferMachineOrder = typeof params.machinetypeId === "number"
|
||||
const hasMachineFilter = Array.isArray(params.machinetypeId)
|
||||
? params.machinetypeId.length > 0
|
||||
: typeof params.machinetypeId === "number";
|
||||
const preferMachineOrder = hasMachineFilter
|
||||
? null
|
||||
: sql`case
|
||||
when ${entries.machinetypeId} = 27 then 0
|
||||
@@ -190,7 +193,7 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
|
||||
if (q.length === 0) {
|
||||
// Default listing: return first page by id desc (no guaranteed ordering field; using id)
|
||||
// Apply optional filters even without q
|
||||
const whereClauses: Array<ReturnType<typeof eq>> = [];
|
||||
const whereClauses: Array<ReturnType<typeof sql>> = [];
|
||||
if (typeof params.genreId === "number") {
|
||||
whereClauses.push(eq(entries.genretypeId, params.genreId));
|
||||
}
|
||||
@@ -199,6 +202,9 @@ export async function searchEntries(params: SearchParams): Promise<PagedResult<S
|
||||
}
|
||||
if (typeof params.machinetypeId === "number") {
|
||||
whereClauses.push(eq(entries.machinetypeId, params.machinetypeId));
|
||||
} else if (Array.isArray(params.machinetypeId) && params.machinetypeId.length > 0) {
|
||||
const ids = params.machinetypeId.map((id) => sql`${id}`);
|
||||
whereClauses.push(sql`${entries.machinetypeId} in (${sql.join(ids, sql`, `)})`);
|
||||
}
|
||||
|
||||
const whereExpr = whereClauses.length ? and(...whereClauses) : undefined;
|
||||
@@ -1655,7 +1661,12 @@ export async function getEntryFacets(params: SearchParams): Promise<EntryFacets>
|
||||
}
|
||||
if (params.genreId) whereParts.push(sql`e.genretype_id = ${params.genreId}`);
|
||||
if (params.languageId) whereParts.push(sql`e.language_id = ${params.languageId}`);
|
||||
if (params.machinetypeId) whereParts.push(sql`e.machinetype_id = ${params.machinetypeId}`);
|
||||
if (typeof params.machinetypeId === "number") {
|
||||
whereParts.push(sql`e.machinetype_id = ${params.machinetypeId}`);
|
||||
} else if (Array.isArray(params.machinetypeId) && params.machinetypeId.length > 0) {
|
||||
const ids = params.machinetypeId.map((id) => sql`${id}`);
|
||||
whereParts.push(sql`e.machinetype_id in (${sql.join(ids, sql`, `)})`);
|
||||
}
|
||||
|
||||
const whereSql = whereParts.length ? sql.join([sql`where `, sql.join(whereParts, sql` and `)], sql``) : sql``;
|
||||
|
||||
@@ -1733,7 +1744,7 @@ export interface ReleaseSearchParams {
|
||||
sort?: "year_desc" | "year_asc" | "title" | "entry_id_desc";
|
||||
// Optional download-based filters (matched via EXISTS on downloads)
|
||||
dLanguageId?: string; // downloads.language_id
|
||||
dMachinetypeId?: number; // downloads.machinetype_id
|
||||
dMachinetypeId?: number | number[]; // downloads.machinetype_id
|
||||
filetypeId?: number; // downloads.filetype_id
|
||||
schemetypeId?: string; // downloads.schemetype_id
|
||||
sourcetypeId?: string; // downloads.sourcetype_id
|
||||
@@ -1754,7 +1765,10 @@ export async function searchReleases(params: ReleaseSearchParams): Promise<Paged
|
||||
const pageSize = Math.max(1, Math.min(params.pageSize ?? 20, 100));
|
||||
const page = Math.max(1, params.page ?? 1);
|
||||
const offset = (page - 1) * pageSize;
|
||||
const preferMachineOrder = params.dMachinetypeId != null
|
||||
const hasMachineFilter = Array.isArray(params.dMachinetypeId)
|
||||
? params.dMachinetypeId.length > 0
|
||||
: params.dMachinetypeId != null;
|
||||
const preferMachineOrder = hasMachineFilter
|
||||
? null
|
||||
: sql`case
|
||||
when ${entries.machinetypeId} = 27 then 0
|
||||
@@ -1780,7 +1794,12 @@ export async function searchReleases(params: ReleaseSearchParams): Promise<Paged
|
||||
// would produce "from `d`" which MySQL interprets as a literal table.
|
||||
const dlConds: Array<ReturnType<typeof sql>> = [];
|
||||
if (params.dLanguageId) dlConds.push(sql`d.language_id = ${params.dLanguageId}`);
|
||||
if (params.dMachinetypeId != null) dlConds.push(sql`d.machinetype_id = ${params.dMachinetypeId}`);
|
||||
if (typeof params.dMachinetypeId === "number") {
|
||||
dlConds.push(sql`d.machinetype_id = ${params.dMachinetypeId}`);
|
||||
} else if (Array.isArray(params.dMachinetypeId) && params.dMachinetypeId.length > 0) {
|
||||
const ids = params.dMachinetypeId.map((id) => sql`${id}`);
|
||||
dlConds.push(sql`d.machinetype_id in (${sql.join(ids, sql`, `)})`);
|
||||
}
|
||||
if (params.filetypeId != null) dlConds.push(sql`d.filetype_id = ${params.filetypeId}`);
|
||||
if (params.schemetypeId) dlConds.push(sql`d.schemetype_id = ${params.schemetypeId}`);
|
||||
if (params.sourcetypeId) dlConds.push(sql`d.sourcetype_id = ${params.sourcetypeId}`);
|
||||
|
||||
Reference in New Issue
Block a user