Podcast workflow: Finished seasons section grouping fully released seasons; v2.18.0
Publish Container / build (push) Successful in 16m19s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-12 10:34:44 -04:00
1 parent 1bf11a3669
commit 69d445013a
3 files changed
+30 -4

No files matched your search

+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "siteforge",
"version": "2.17.3",
"version": "2.18.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "siteforge",
"version": "2.17.3",
"version": "2.18.0",
"dependencies": {
"@aws-sdk/client-s3": "^3.1135.0",
"@dnd-kit/core": "^6.3.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "siteforge",
"private": true,
"version": "2.17.3",
"version": "2.18.0",
"type": "module",
"scripts": {
"dev": "vite",
+27 -1
View File
@@ -1875,7 +1875,17 @@ function PodcastWorkflowAdmin({ laneA, laneB }: { laneA: { title: string }; lane
const hasOther = items.some(i => i.lane === 'other')
const inLane = items.filter(i => i.lane === lane)
const upcoming = inLane.filter(i => !i.released)
const released = inLane.filter(i => i.released)
// A season is finished once none of its episodes are still in progress. Only the "Other seasons"
// tab groups these away; a lane's own season is always shown as current.
const seasonGroups = new Map<string, PodcastWorkflowItem[]>()
if (lane === 'other') {
for (const i of inLane) seasonGroups.set(i.season, [...(seasonGroups.get(i.season) ?? []), i])
}
const finishedSeasons = [...seasonGroups.entries()]
.filter(([, eps]) => eps.every(e => e.released))
.sort(([a], [b]) => (Number(b) || 0) - (Number(a) || 0))
const finishedKeys = new Set(finishedSeasons.flatMap(([, eps]) => eps.map(e => e.key)))
const released = inLane.filter(i => i.released && !finishedKeys.has(i.key))
const selected = items.find(i => i.key === selectedKey) ?? null
const save = async (key: string, patch: Record<string, unknown>) => {
@@ -2024,6 +2034,22 @@ function PodcastWorkflowAdmin({ laneA, laneB }: { laneA: { title: string }; lane
<input type="checkbox" checked={showReleased} onChange={e => setShowReleased(e.target.checked)} /> Show released ({released.length})
</label>
{showReleased && released.map(row)}
{finishedSeasons.length > 0 && (
<div style={{ marginTop: 14 }}>
<strong style={{ fontSize: '0.82rem' }}>Finished seasons</strong>
{finishedSeasons.map(([season, eps]) => {
const last = eps.map(e => e.releaseDate ?? '').sort().pop()
return (
<details key={season || 'none'} style={{ marginTop: 6 }}>
<summary style={{ cursor: 'pointer', padding: '6px 2px' }}>
{season ? `Season ${season}` : 'No season number'} — {eps.length} episode{eps.length === 1 ? '' : 's'}{last ? ` · last released ${last}` : ''}
</summary>
{eps.map(row)}
</details>
)
})}
</div>
)}
</div>
<div>