release: v0.14.0

Fourteen commits since v0.13.0. See CHANGELOG.md for the full list.

Two additions: `npm run doctor`, which runs the config doctor from a terminal — including inside the shipped image — and exits with the worst finding, so it can gate a deployment script; and a Playwright spec that loads all fourteen admin routes against a production build.

One change, invisible on screen: the admin panel got a form-field layer (#533).

Five fixes: grid.gap on both axes (#513), the dashboard status badge (#539), the journal editor's unsaved-changes guard (#538), essay paragraph markup (#537), and aria-pressed on the panel's switches and pickers.
This commit is contained in:
Ralksta
2026-08-30 15:11:25 +02:00
committed by GitHub
parent a813433891
commit e99d3f2f1b
59 changed files with 8652 additions and 6676 deletions

View File

@@ -241,13 +241,20 @@ export function EssayBlockEditor({ markdown, onChange, onSelectPhoto }: EssayBlo
</div>
)}
{/* 2. PARAGRAPH BLOCK */}
{/* 2. PARAGRAPH BLOCK
The textarea shows `html` raw, as the journal editor does. It used
to strip the tags for display — `<strong>` to `**`, everything else
to nothing — while `onChange` wrote the stripped text straight back
into `html`. Italics, links, anything the markdown had produced was
destroyed by the act of editing the paragraph, and the two editors
disagreed about the same file. serializeJournalMarkdown() turns the
HTML back into markdown on save and handles `<em>` too, so there
was nothing to convert here in the first place. */}
{block.type === 'paragraph' && (
<textarea
rows={3}
value={block.html.replace(/<[^>]+>/g, (t) =>
t.startsWith('<strong>') ? '**' : t.startsWith('</strong>') ? '**' : '',
)}
value={block.html}
onChange={(e) => handleUpdateBlock(idx, { ...block, html: e.target.value })}
placeholder="Write text paragraph... (**bold**, *italic* markdown supported)"
/>