/* * detail-render.js * HTML-string generators for the right-side detail panel (desktop) and * the selected-entity view (mobile). Covers all four entity types. * * Depends on: S, _bnd (state.js); esc (helpers.js); * pluginsByCategory, pluginsByTarget, vPluginBtn, getBookStats, * vAiProgressBar, candidateSugRows, _STATUS_BADGE (tree-render.js); * parseBounds, parseBndPluginResults (canvas-boundary.js) * Provides: vDetailBody(), vRoomDetail(), vCabinetDetail(), * vShelfDetail(), vBookDetail() */ // ── Room detail ────────────────────────────────────────────────────────────── function vRoomDetail(r) { const stats = getBookStats(r, 'room'); const totalBooks = stats.total; return `
${vAiProgressBar(stats)}

${r.cabinets.length} cabinet${r.cabinets.length!==1?'s':''} · ${totalBooks} book${totalBooks!==1?'s':''}

`; } // ── Detail body (right panel) ──────────────────────────────────────────────── function vDetailBody() { if (!S.selected) return '
← Select a room, cabinet or shelf from the tree
'; const {type, id} = S.selected; const node = findNode(id); if (!node) return '
Not found
'; if (type === 'room') return vRoomDetail(node); if (type === 'cabinet') return vCabinetDetail(node); if (type === 'shelf') return vShelfDetail(node); if (type === 'book') return vBookDetail(node); return ''; } // ── Cabinet detail ─────────────────────────────────────────────────────────── function vCabinetDetail(cab) { const bounds = parseBounds(cab.shelf_boundaries); const hasPhoto = !!cab.photo_filename; const stats = getBookStats(cab, 'cabinet'); const bndPlugins = pluginsByTarget('boundary_detector', 'shelves'); const pluginResults = parseBndPluginResults(cab.ai_shelf_boundaries); const pluginIds = Object.keys(pluginResults); const sel = (_bnd?.nodeId === cab.id) ? _bnd.selectedPlugin : (cab.shelves.length > 0 ? null : pluginIds[0] ?? null); const selOpts = [ ``, ...pluginIds.map(pid => ``), ...(pluginIds.length > 1 ? [``] : []), ].join(''); return `
${vAiProgressBar(stats)} ${hasPhoto ? `
` : `
📷
Upload a cabinet photo (📷 in header) to get started
`} ${hasPhoto ? `

Drag lines · Ctrl+Alt+Click to add · Snap to AI guides

` : ''} ${hasPhoto ? `
${bounds.length ? `${cab.shelves.length} shelf${cab.shelves.length!==1?'s':''} · ${bounds.length} boundar${bounds.length!==1?'ies':'y'}` : ''}
${bndPlugins.map(p => vPluginBtn(p, cab.id, 'cabinets')).join('')}
` : ''}
`; } // ── Shelf detail ───────────────────────────────────────────────────────────── function vShelfDetail(shelf) { const bounds = parseBounds(shelf.book_boundaries); const stats = getBookStats(shelf, 'shelf'); const bndPlugins = pluginsByTarget('boundary_detector', 'books'); const pluginResults = parseBndPluginResults(shelf.ai_book_boundaries); const pluginIds = Object.keys(pluginResults); const sel = (_bnd?.nodeId === shelf.id) ? _bnd.selectedPlugin : (shelf.books.length > 0 ? null : pluginIds[0] ?? null); const selOpts = [ ``, ...pluginIds.map(pid => ``), ...(pluginIds.length > 1 ? [``] : []), ].join(''); return `
${vAiProgressBar(stats)}

Drag lines · Ctrl+Alt+Click to add · Snap to AI guides

${bounds.length ? `${shelf.books.length} book${shelf.books.length!==1?'s':''} · ${bounds.length} boundary${bounds.length!==1?'ies':''}` : ''}
${bndPlugins.map(p => vPluginBtn(p, shelf.id, 'shelves')).join('')}
`; } // ── Book detail ────────────────────────────────────────────────────────────── function vBookDetail(b) { const [sc, sl] = _STATUS_BADGE[b.identification_status] ?? _STATUS_BADGE.unidentified; const recognizers = pluginsByCategory('text_recognizer'); const identifiers = pluginsByCategory('book_identifier'); const searchers = pluginsByCategory('archive_searcher'); const hasRawText = !!(b.raw_text || '').trim(); return `
Spine
${b.image_filename ? `
Title page
` : ''}
${sl} ${b.identification_status ?? 'unidentified'} ${b.analyzed_at ? `Identified ${b.analyzed_at.slice(0,10)}` : ''}
${searchers.length ? `
` : ''}
${candidateSugRows(b, 'title', 'd-title')}
${candidateSugRows(b, 'author', 'd-author')}
${candidateSugRows(b, 'year', 'd-year')}
${candidateSugRows(b, 'isbn', 'd-isbn')}
${candidateSugRows(b, 'publisher', 'd-pub')}
`; }