Fix issues #2-#6 and #8: searchable pickers, occupancy filter, asset UX, counts

- #2 #5: Replace plain <select> location pickers in NewTask and Assets with
  SearchSelect combobox — full-text search across name and category group
- #3: Add "Unknown" checkbox on asset install date — disables the field and
  saves null instead of leaving an ambiguous blank
- #4: Add inline "Add service task" form in asset detail modal — creates a
  recurring template pre-linked to the asset without leaving the page
- #6: Fix unoccupied rooms filter — was always empty because (a) list_type
  was 'all' instead of 'staying' and (b) only checked b.site_id but NewBook
  returns booking_site_id on most account configs
- #8: Add open-task count badges to category filter chips on Summary page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-08 12:09:57 +00:00
parent 2a3a226131
commit 859874f614
6 changed files with 268 additions and 39 deletions

View file

@ -52,6 +52,12 @@ export default function Summary() {
return c
}, [tasks])
const categoryCounts = useMemo(() => {
const c: Record<number, number> = {}
for (const t of tasks) c[t.category_id] = (c[t.category_id] || 0) + 1
return c
}, [tasks])
const roomsCategoryExists = categories.some(c => c.is_rooms)
return (
@ -84,7 +90,7 @@ export default function Summary() {
<div className="chip-bar">
{categories.map(c => (
<button key={c.id} className={`chip ${categoryFilter === c.id ? 'active' : ''}`} onClick={() => setCategoryFilter(categoryFilter === c.id ? null : c.id)}>
{c.name}
{c.name}{categoryCounts[c.id] ? ` (${categoryCounts[c.id]})` : ''}
</button>
))}
<button className={`chip ${mineOnly ? 'active' : ''}`} onClick={() => setMineOnly(!mineOnly)}>