Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: smart Forge folder for auto-generated session reports

Adds a virtual "Forge" folder that appears in the landing page when
documents tagged with "forge-report" exist. Clicking it filters to
show only Forge session reports.

- Smart folder renders before user folders with a subtle accent border
- Click handler sets the tag filter (reuses existing tag infrastructure)
- No new API endpoints needed — uses existing tags system

+41 -1
+6
src/css/app.css
··· 1384 1384 border-color: var(--color-border-strong); 1385 1385 background: var(--color-hover); 1386 1386 } 1387 + .folder-card--smart { 1388 + border-color: oklch(0.55 0.08 250); 1389 + } 1390 + .folder-card--smart:hover { 1391 + border-color: oklch(0.65 0.12 250); 1392 + } 1387 1393 1388 1394 .folder-card-icon { 1389 1395 font-size: 1.4rem;
+11
src/landing-events-folders.ts
··· 61 61 return; 62 62 } 63 63 64 + // Smart folder click — filter by tag 65 + const smartCard = target.closest('.folder-card--smart') as HTMLElement | null; 66 + if (smartCard) { 67 + const tag = smartCard.dataset.smartTag; 68 + if (tag) { 69 + deps.setActiveTagFilter(tag); 70 + deps.renderDocuments(); 71 + } 72 + return; 73 + } 74 + 64 75 // Navigate into folder (but not if clicking actions) 65 76 const card = target.closest('.folder-card') as HTMLElement | null; 66 77 if (card && !target.closest('.folder-card-actions')) {
+24 -1
src/landing-render.ts
··· 192 192 193 193 // ── Folders ────────────────────────────────────────────────── 194 194 195 + // Smart folders: auto-generated from tags (e.g., "forge-report" → Forge folder). 196 + const SMART_FOLDERS: Array<{ tag: string; name: string; icon: string }> = [ 197 + { tag: 'forge-report', name: 'Forge', icon: '\u2692' }, // ⚒ 198 + ]; 199 + 195 200 export function renderFolders(deps: RenderDeps, activeDocs: DocumentMeta[]): void { 196 201 const currentFolderId = deps.getCurrentFolderId(); 197 202 const searchQuery = deps.getSearchQuery(); ··· 204 209 return; 205 210 } 206 211 207 - if (folders.length === 0) { 212 + // Build smart folders from tagged docs 213 + const smartFolderCards: string[] = []; 214 + for (const sf of SMART_FOLDERS) { 215 + const tagged = filterByTag(activeDocs, sf.tag) as DocumentMeta[]; 216 + if (tagged.length > 0) { 217 + // Smart folders use tag: prefix as their folder ID 218 + smartFolderCards.push(` 219 + <div class="folder-card folder-card--smart" data-smart-tag="${escapeHtml(sf.tag)}"> 220 + <span class="folder-card-icon">${sf.icon}</span> 221 + <span class="folder-card-name">${escapeHtml(sf.name)}</span> 222 + <span class="folder-card-count">${tagged.length} doc${tagged.length !== 1 ? 's' : ''}</span> 223 + </div>`); 224 + } 225 + } 226 + 227 + if (folders.length === 0 && smartFolderCards.length === 0) { 208 228 deps.folderListEl.innerHTML = ''; 209 229 return; 210 230 } 211 231 212 232 let html = '<div class="folder-grid">'; 233 + // Smart folders first 234 + html += smartFolderCards.join(''); 235 + // User folders 213 236 for (const folder of folders) { 214 237 const docCount = activeDocs.filter(d => folderAssignments[d.id] === folder.id).length; 215 238 html += `