v0.1.36 - What's new dialog: historical changelog accordion

Add a "Read previous changes" accordion to the What's new dialog and
backfill the changelog history from git.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 12:36:17 +12:00
co-authored by Claude Opus 4.8
parent dc50e0538e
commit 5a4d9d77e5
5 changed files with 213 additions and 12 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "hunter-backend" name = "hunter-backend"
version = "0.1.35" version = "0.1.36"
description = "Costing platform MVP backend (API for Hunter)" description = "Costing platform MVP backend (API for Hunter)"
requires-python = ">=3.11" requires-python = ">=3.11"
dependencies = [ dependencies = [
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "hunter-app", "name": "hunter-app",
"version": "0.1.35", "version": "0.1.36",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "hunter-app", "name": "hunter-app",
"version": "0.1.35", "version": "0.1.36",
"dependencies": { "dependencies": {
"@fontsource/inter": "^5.2.8", "@fontsource/inter": "^5.2.8",
"lucide-svelte": "^1.0.1" "lucide-svelte": "^1.0.1"
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "hunter-app", "name": "hunter-app",
"version": "0.1.35", "version": "0.1.36",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+81 -3
View File
@@ -17,6 +17,14 @@ export type ChangelogEntry = {
export const APP_VERSION: string = packageInfo.version; export const APP_VERSION: string = packageInfo.version;
export const changelog: ChangelogEntry[] = [ export const changelog: ChangelogEntry[] = [
{
version: '0.1.36',
date: '2026-06-21',
highlights: [
'App: Bug fixes & improvements.',
'App: General improvements.'
]
},
{ {
version: '0.1.35', version: '0.1.35',
date: '2026-06-21', date: '2026-06-21',
@@ -41,12 +49,60 @@ export const changelog: ChangelogEntry[] = [
'App: Bug fixes & improvements.' 'App: Bug fixes & improvements.'
] ]
}, },
{
version: '0.1.32',
date: '2026-06-21',
highlights: [
'Mix Calculator: Added search.',
'Ingredients: Added ingredient categories.',
'Throughput: Tidy-up and refinements.'
]
},
{ {
version: '0.1.31', version: '0.1.31',
date: '2026-06-18', date: '2026-06-18',
highlights: [ highlights: [
'App: Bug fixes & improvements.', 'Mix Editor: Multi-row editing.',
'App: Throughput module is now live.' 'App: Bug fixes & improvements.'
]
},
{
version: '0.1.30',
date: '2026-06-18',
highlights: [
'Throughput: Overview now shows today-only mix cards.',
'Mix Editor: Fixed an error when saving a mix formula.'
]
},
{
version: '0.1.29',
date: '2026-06-18',
highlights: [
'Mix Editor: Editing a % no longer rebalances the other ingredients.'
]
},
{
version: '0.1.28',
date: '2026-06-17',
highlights: [
'Editor & Throughput: Updates and improvements.'
]
},
{
version: '0.1.27',
date: '2026-06-16',
highlights: [
'Editor: Edit a mixs resolved formula directly, with % and kg entry on each row.',
'Editor: New mix and new ingredient buttons.',
'Throughput: Power BI / external API now live.',
'App: Security hardening on API responses.'
]
},
{
version: '0.1.23',
date: '2026-06-15',
highlights: [
'App: Improvements & bug fixes.'
] ]
}, },
{ {
@@ -56,6 +112,13 @@ export const changelog: ChangelogEntry[] = [
'Web App - Throughput module is now live.' 'Web App - Throughput module is now live.'
] ]
}, },
{
version: '0.1.21',
date: '2026-06-14',
highlights: [
'Mix Calculator: Composer restyle.'
]
},
{ {
version: '0.1.20', version: '0.1.20',
date: '2026-06-13', date: '2026-06-13',
@@ -64,6 +127,14 @@ export const changelog: ChangelogEntry[] = [
'App - Bug fixes' 'App - Bug fixes'
] ]
}, },
{
version: '0.1.19',
date: '2026-06-13',
highlights: [
'Throughput: Overview view added.',
'App: Responsive header.'
]
},
{ {
version: '0.1.18', version: '0.1.18',
date: '2026-06-12', date: '2026-06-12',
@@ -94,9 +165,16 @@ export const changelog: ChangelogEntry[] = [
highlights: [ highlights: [
'Mix Calculator: Changed from selecting Product to Mix.', 'Mix Calculator: Changed from selecting Product to Mix.',
'Web app design improved', 'Web app design improved',
'Throughput tab ready for testing', 'Throughput tab ready for testing',
'Costing Editor tab ready for testing' 'Costing Editor tab ready for testing'
] ]
},
{
version: '0.1.11',
date: '2026-06-03',
highlights: [
'Costing Editor: First release.'
]
} }
]; ];
@@ -1,16 +1,22 @@
<script lang="ts"> <script lang="ts">
import { Sparkles } from 'lucide-svelte'; import { Sparkles } from 'lucide-svelte';
import type { ChangelogEntry } from '$lib/changelog'; import { changelog, type ChangelogEntry } from '$lib/changelog';
let { entry, onClose }: { entry: ChangelogEntry; onClose: () => void } = $props(); let { entry, onClose }: { entry: ChangelogEntry; onClose: () => void } = $props();
const releaseDate = $derived( function formatDate(date: string): string {
new Date(`${entry.date}T00:00:00`).toLocaleDateString(undefined, { return new Date(`${date}T00:00:00`).toLocaleDateString(undefined, {
year: 'numeric', year: 'numeric',
month: 'long', month: 'long',
day: 'numeric' day: 'numeric'
}) });
); }
const releaseDate = $derived(formatDate(entry.date));
// Every release older than the one being shown, newest first, for the
// "Read previous changes" accordion.
const previousEntries = $derived(changelog.filter((item) => item.version !== entry.version));
</script> </script>
<div class="whats-new-backdrop" role="presentation" onclick={onClose}> <div class="whats-new-backdrop" role="presentation" onclick={onClose}>
@@ -42,6 +48,27 @@
{/each} {/each}
</ul> </ul>
{#if previousEntries.length}
<details class="whats-new-history">
<summary>Read previous changes</summary>
<ol class="history-list">
{#each previousEntries as item (item.version)}
<li class="history-entry">
<div class="history-head">
<span class="history-version">v{item.version}</span>
<span class="history-date">{formatDate(item.date)}</span>
</div>
<ul class="history-highlights">
{#each item.highlights as highlight}
<li>{highlight}</li>
{/each}
</ul>
</li>
{/each}
</ol>
</details>
{/if}
<div class="whats-new-actions"> <div class="whats-new-actions">
<button class="whats-new-button" type="button" onclick={onClose}>Got it</button> <button class="whats-new-button" type="button" onclick={onClose}>Got it</button>
</div> </div>
@@ -141,6 +168,102 @@
background: var(--color-brand); background: var(--color-brand);
} }
.whats-new-history {
border-top: 1px solid var(--color-divider);
padding-top: 1.05rem;
}
.whats-new-history > summary {
display: inline-flex;
align-items: center;
list-style: none;
color: var(--color-brand);
font-size: 0.86rem;
font-weight: 600;
cursor: pointer;
user-select: none;
}
.whats-new-history > summary::-webkit-details-marker {
display: none;
}
.whats-new-history > summary::before {
content: '';
width: 0.46rem;
height: 0.46rem;
margin-right: 0.55rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(-45deg);
transition: transform 160ms ease;
}
.whats-new-history[open] > summary::before {
transform: rotate(45deg);
}
.whats-new-history > summary:focus-visible {
outline: 3px solid color-mix(in srgb, var(--color-brand) 45%, transparent);
outline-offset: 2px;
border-radius: 0.3rem;
}
.history-list {
display: grid;
gap: 1.05rem;
margin: 1rem 0 0;
padding: 0;
list-style: none;
max-height: 16rem;
overflow-y: auto;
}
.history-head {
display: flex;
align-items: baseline;
gap: 0.6rem;
margin-bottom: 0.4rem;
}
.history-version {
font-size: 0.84rem;
font-weight: 700;
color: var(--color-text-primary);
}
.history-date {
font-size: 0.76rem;
color: var(--color-text-muted);
}
.history-highlights {
display: grid;
gap: 0.4rem;
margin: 0;
padding: 0;
list-style: none;
}
.history-highlights li {
position: relative;
padding-left: 1.1rem;
color: var(--color-text-secondary);
font-size: 0.86rem;
line-height: 1.45;
}
.history-highlights li::before {
content: '';
position: absolute;
top: 0.5rem;
left: 0.15rem;
width: 0.34rem;
height: 0.34rem;
border-radius: 999px;
background: var(--color-text-muted);
}
.whats-new-actions { .whats-new-actions {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;