Skip to content

Commit 9533e0e

Browse files
authored
Merge pull request #1083 from SlideRuleEarth/release_notes
Release Notes Landing Page Update
2 parents 42634ef + 691a22d commit 9533e0e

1 file changed

Lines changed: 21 additions & 45 deletions

File tree

web-client/src/views/LandingView.vue

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function stripFrontmatter(md: string): string {
1515
const aboutHtml = DOMPurify.sanitize(marked(stripFrontmatter(aboutRaw)) as string)
1616
const contactHtml = DOMPurify.sanitize(marked(stripFrontmatter(contactRaw)) as string)
1717
18-
const tabOptions = ['About', 'Contact', 'SlideRule Releases', 'Web Client Releases']
18+
const tabOptions = ['About', 'Contact', 'Release Notes']
1919
const selectedTab = ref('About')
2020
2121
const panelHtml = computed(() => {
@@ -30,11 +30,6 @@ const panelHtml = computed(() => {
3030
})
3131
3232
// --- Release Notes ---
33-
//
34-
// Two release-note sources share the list/detail UI below:
35-
// - 'remote' = the SlideRule platform notes scraped from the docs site
36-
// - 'local' = this repo's web-client notes, bundled at build time (see the
37-
// import.meta.glob of src/assets/content/release-notes/*.md)
3833
3934
const RELEASE_NOTES_INDEX_URL = DOCS.releaseNotes.index
4035
const RELEASE_NOTES_BASE_URL = DOCS.releaseNotes.base
@@ -53,11 +48,7 @@ const releaseHtml = ref('')
5348
const releaseLoading = ref(false)
5449
const releaseError = ref('')
5550
56-
const releaseMode = computed<'remote' | 'local' | null>(() => {
57-
if (selectedTab.value === 'SlideRule Releases') return 'remote'
58-
if (selectedTab.value === 'Web Client Releases') return 'local'
59-
return null
60-
})
51+
const showReleaseNotes = computed(() => selectedTab.value === 'Release Notes')
6152
6253
// --- Local web-client release notes (bundled markdown) ---
6354
@@ -67,24 +58,6 @@ const localNoteModules = import.meta.glob('@/assets/content/release-notes/*.md',
6758
eager: true
6859
}) as Record<string, string>
6960
70-
function versionKey(v: string): number[] {
71-
return v
72-
.replace(/^v/, '')
73-
.split('.')
74-
.map((n) => parseInt(n, 10) || 0)
75-
}
76-
77-
// Sort newest-first by semantic version (v4.5.10 after v4.5.2).
78-
function compareVersionDesc(a: string, b: string): number {
79-
const av = versionKey(a)
80-
const bv = versionKey(b)
81-
for (let i = 0; i < Math.max(av.length, bv.length); i++) {
82-
const diff = (bv[i] ?? 0) - (av[i] ?? 0)
83-
if (diff !== 0) return diff
84-
}
85-
return 0
86-
}
87-
8861
const localReleaseNotes = computed<ReleaseNote[]>(() => {
8962
const notes = Object.entries(localNoteModules).map(([path, raw]) => {
9063
const version = path.split('/').pop()?.replace(/\.md$/, '') ?? ''
@@ -97,33 +70,38 @@ const localReleaseNotes = computed<ReleaseNote[]>(() => {
9770
const bullet = body.match(/^\s*[-*]\s+(.+)$/m)
9871
const snippet = bullet?.[1] ?? ''
9972
const html = DOMPurify.sanitize(marked(body) as string)
100-
return { title, date, url: DOCS.webClient.tags + version, snippet, html }
73+
return {
74+
title: 'Web Client - ' + title,
75+
date,
76+
url: DOCS.webClient.tags + version,
77+
snippet,
78+
html
79+
}
10180
})
102-
return notes.sort((a, b) => compareVersionDesc(a.title, b.title) || b.date.localeCompare(a.date))
81+
return notes.sort((a, b) => b.date.localeCompare(a.date))
10382
})
10483
10584
const currentNotes = computed<ReleaseNote[]>(() => {
106-
if (releaseMode.value === 'local') return localReleaseNotes.value
107-
if (releaseMode.value === 'remote') return releaseNotes.value
108-
return []
85+
if (!showReleaseNotes.value) return []
86+
const combined = [...releaseNotes.value, ...localReleaseNotes.value]
87+
return combined.sort((a, b) => b.date.localeCompare(a.date))
10988
})
11089
11190
const externalLink = computed(() => {
11291
if (!selectedRelease.value) return ''
113-
return releaseMode.value === 'local'
92+
return selectedRelease.value.html
11493
? selectedRelease.value.url
11594
: RELEASE_NOTES_BASE_URL + selectedRelease.value.url
11695
})
11796
11897
const externalLinkLabel = computed(() =>
119-
releaseMode.value === 'local' ? 'View on GitHub ↗' : 'View on docs site ↗'
98+
selectedRelease.value?.html ? 'View on GitHub ↗' : 'View on docs site ↗'
12099
)
121100
122101
function openRelease(note: ReleaseNote) {
123-
if (releaseMode.value === 'local') {
124-
// Local notes are already rendered — no network fetch needed.
102+
if (note.html) {
125103
selectedRelease.value = note
126-
releaseHtml.value = note.html ?? ''
104+
releaseHtml.value = note.html
127105
} else {
128106
void fetchRelease(note)
129107
}
@@ -146,7 +124,7 @@ async function fetchReleaseNotesIndex() {
146124
// Matches "Release v5.4.x", "Release v5.4.1", "Web Client Release v4.5.0", etc.
147125
const match = text.match(/^(?:Web Client )?Release v[\d.x]+$/)
148126
if (match) {
149-
notes.push({ date: '', title: text, url: href })
127+
notes.push({ date: '', title: 'Server - ' + text, url: href })
150128
}
151129
})
152130
releaseNotes.value = notes
@@ -237,12 +215,10 @@ onMounted(() => {
237215
})
238216
239217
watch(selectedTab, (tab) => {
240-
// Reset the detail view whenever the tab changes; only the remote source needs
241-
// an on-switch fetch (local notes are bundled and rendered eagerly).
242218
selectedRelease.value = null
243219
releaseHtml.value = ''
244220
releaseError.value = ''
245-
if (tab === 'SlideRule Releases') {
221+
if (tab === 'Release Notes') {
246222
void fetchReleaseNotesIndex()
247223
}
248224
})
@@ -261,7 +237,7 @@ watch(selectedTab, (tab) => {
261237
</div>
262238
</div>
263239
<!-- About / Contact -->
264-
<div v-if="releaseMode === null" ref="panelRef" class="sr-landing-panel">
240+
<div v-if="!showReleaseNotes" ref="panelRef" class="sr-landing-panel">
265241
<div v-if="panelHtml" class="sr-landing-panel-content">
266242
<div v-html="panelHtml" />
267243
</div>
@@ -270,7 +246,7 @@ watch(selectedTab, (tab) => {
270246
</div>
271247
</div>
272248

273-
<!-- Release Notes (SlideRule platform = remote, Web Client = local) -->
249+
<!-- Release Notes (combined: server + web client) -->
274250
<div v-else class="sr-landing-panel">
275251
<div v-if="releaseLoading" class="sr-news-status">Loading...</div>
276252
<div v-else-if="releaseError" class="sr-news-status sr-news-error">{{ releaseError }}</div>

0 commit comments

Comments
 (0)