Files
bambuddy/frontend/src/utils/inventorySearch.ts
T

51 lines
2.1 KiB
TypeScript

import type { InventorySpool } from '../api/client';
import { resolveSpoolColorName } from './colors';
/**
* Return true when spool matches the search query across all searchable text fields.
* Case-insensitive. Empty query always returns true.
*/
export function spoolMatchesQuery(spool: InventorySpool, query: string): boolean {
const q = query.trim().toLowerCase();
if (!q) return true;
// A hash-prefixed number is an explicit spool ID lookup. Keep plain numeric
// searches backwards-compatible ("3" can still match #3, #13, #30, ...),
// while "#3" selects only the physical spool whose label says #3.
const exactIdQuery = q.match(/^#(\d+)$/);
if (exactIdQuery) {
return spool.id === Number(exactIdQuery[1]);
}
return (
String(spool.id).includes(q) ||
spool.material.toLowerCase().includes(q) ||
(spool.brand?.toLowerCase().includes(q) ?? false) ||
// Both the stored name and the displayed one. They differ often: a Bambu
// tag may carry no colour name or an internal code, and Spoolman has no
// such field, so what the list shows is usually resolved from the swatch's
// hex. Searching only the stored value means typing what you can plainly
// read finds nothing (#3090).
(spool.color_name?.toLowerCase().includes(q) ?? false) ||
(resolveSpoolColorName(spool.color_name, spool.rgba, spool.color_name_is_synthesized)
?.toLowerCase()
.includes(q) ??
false) ||
(spool.subtype?.toLowerCase().includes(q) ?? false) ||
(spool.note?.toLowerCase().includes(q) ?? false) ||
(spool.slicer_filament_name?.toLowerCase().includes(q) ?? false) ||
(spool.storage_location?.toLowerCase().includes(q) ?? false) ||
(spool.suppliers?.some(
(link) =>
link.supplier_name.toLowerCase().includes(q) ||
(link.supplier_article_number?.toLowerCase().includes(q) ?? false)
) ?? false)
);
}
/** Filter a spool list by a free-text search query. */
export function filterSpoolsByQuery(spools: InventorySpool[], query: string): InventorySpool[] {
if (!query) return spools;
return spools.filter((spool) => spoolMatchesQuery(spool, query));
}