/** Shared UI helpers for inventory pages (parity with CI views). */ export function gradeLabel(cat: Record | null | undefined): string { if (!cat) return '—' const gmin = cat.grade_min const gmax = cat.grade_max if (gmin == null && gmax == null) return '—' const nmin = typeof gmin === 'number' ? gmin : gmin !== '' ? Number(gmin) : null const nmax = typeof gmax === 'number' ? gmax : gmax !== '' ? Number(gmax) : null if (nmin != null && Number.isFinite(nmin) && nmax != null && Number.isFinite(nmax)) return `G${Math.floor(nmin)}–G${Math.floor(nmax)}` if (nmin != null && Number.isFinite(nmin)) return `G${Math.floor(nmin)}+` if (nmax != null && Number.isFinite(nmax)) return `≤G${Math.floor(nmax)}` return '—' } export function catLabelBook(c: Record): string { let name = String(c.name ?? '') const gl = gradeLabel(c) if (gl !== '—') name += ` (${gl})` return name } export function conditionBadgeClass(condition: unknown): string { const map: Record = { good: 'success', needs_repair: 'warning', need_replace: 'danger', cannot_find: 'secondary', } const k = typeof condition === 'string' ? condition : '' return map[k] ?? 'light' } export function formatConditionLabel(condition: unknown): string { if (condition == null || condition === '') return '' return String(condition) .split('_') .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) .join(' ') } export function parseInventoryList(data: unknown): { items: Record[] categories: Record[] userNames: Record } { if (!data || typeof data !== 'object') return { items: [], categories: [], userNames: {} } const o = data as Record const items = Array.isArray(o.items) ? (o.items as Record[]) : [] const categories = Array.isArray(o.categories) ? (o.categories as Record[]) : [] const userNames = o.userNames && typeof o.userNames === 'object' ? (o.userNames as Record) : {} return { items, categories, userNames } } export function userDisplay( userNames: Record, updatedBy: unknown, ): string { const id = typeof updatedBy === 'number' ? updatedBy : Number(updatedBy ?? 0) if (!id) return '—' return userNames[String(id)] ?? userNames[id] ?? '—' } export function parseClassesSelection(item: Record): number[] { const raw = item.classes ?? item.class_list ?? item.class_ids if (Array.isArray(raw)) { return raw.map((x) => Number(x)).filter((n) => n >= 1 && n <= 13) } if (typeof raw === 'string' && raw !== '') { try { const decoded = JSON.parse(raw) as unknown if (Array.isArray(decoded)) { return decoded.map((x) => Number(x)).filter((n) => n >= 1 && n <= 13) } } catch { /* fall through */ } const parts = raw.split(/[,\s]+/) return parts.map((p) => Number(p)).filter((n) => n >= 1 && n <= 13 && Number.isFinite(n)) } return [] }