mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-05 13:41:36 +02:00
51 lines
2.1 KiB
TypeScript
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));
|
|
}
|