diff --git a/TODO.md b/TODO.md index fd7077e..2aaa736 100644 --- a/TODO.md +++ b/TODO.md @@ -8,12 +8,11 @@ ## TODO -- [ ] Display sub-lines of the form `key: value` immediately after item - ## Bugs ## Done +- [x] Display sub-lines of the form `key: value` immediately after item - [x] Project list pulldown in top right - [x] Make it a proper PWA with the minimal-pwa technique - [x] Extract and consolidate indent detection functions diff --git a/index.html b/index.html index 3c97aac..87f03aa 100644 --- a/index.html +++ b/index.html @@ -368,10 +368,11 @@ .card-footer { display: flex; - align-items: center; - justify-content: end; + align-items: flex-start; + justify-content: space-between; font-size: 0.85em; color: var(--shade); + gap: 0.5em; } .card-footer-content { @@ -381,6 +382,13 @@ gap: 0.25em; } + .card-metadata { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 0.25em; + } + .card-expand-indicator { color: var(--shade); font-size: 1.2em; @@ -1273,6 +1281,25 @@ chmod 755 kbtd }); } + function extractMetadata(nestedLines) { + const metadata = []; + const metadataPattern = /^(\w+):\s*(.+)$/; + + for (const line of nestedLines) { + const trimmed = line.trim(); + if (trimmed === '') continue; + + const match = trimmed.match(metadataPattern); + if (match) { + metadata.push({ key: match[1], value: match[2] }); + } else { + break; + } + } + + return metadata; + } + function countSubtasks(nestedLines) { let total = 0; let completed = 0; @@ -2011,6 +2038,7 @@ chmod 755 kbtd if (!state.showCompleted && card.completed) return; const hasNestedContent = card.nestedLines.length > 0; + const metadata = extractMetadata(card.nestedLines); const subtasks = countSubtasks(card.nestedLines); const cardDiv = h('div', { @@ -2107,13 +2135,26 @@ chmod 755 kbtd cardDiv.append(cardHeader, menu); - if (hasNestedContent) { + if (hasNestedContent || metadata.length > 0) { const cardFooter = h('div', { className: 'card-footer' }); - const cardFooterContent = h('div', { className: 'card-footer-content' }); + + if (metadata.length > 0) { + const metadataDiv = h('div', { className: 'card-metadata' }); + metadata.forEach(m => { + const metadataLine = h('span', { + className: 'card-expand-indicator', + textContent: `${m.key}: ${m.value}` + }); + metadataDiv.append(metadataLine); + }); + cardFooter.append(metadataDiv); + } if (subtasks.total > 0) { const percentage = subtasks.total > 0 ? (subtasks.completed / subtasks.total) * 100 : 0; + const cardFooterContent = h('div', { className: 'card-footer-content' }); + const expandIndicator = h('span', { className: 'card-expand-indicator', textContent: `${subtasks.completed} / ${subtasks.total}` @@ -2127,15 +2168,15 @@ chmod 755 kbtd ); cardFooterContent.append(expandIndicator, progressBar); - } else { + cardFooter.append(cardFooterContent); + } else if (metadata.length === 0) { const expandIndicator = h('span', { className: 'card-expand-indicator', textContent: '+' }); - cardFooterContent.append(expandIndicator); + cardFooter.append(expandIndicator); } - cardFooter.append(cardFooterContent); cardDiv.append(cardFooter); }