opsdash-app/opsdash/composables/useVersionOverlay.ts
blade34242 01552e2138
All checks were successful
Nextcloud Server Tests / matrix-config (push) Successful in 19s
Build And Publish Appstore Package / build_and_publish (push) Successful in 3m28s
Nextcloud Server Tests / Nextcloud stable31 / PHP 8.2 (stable31, 8.2) (push) Successful in 19m13s
Nextcloud Server Tests / version-consistency (push) Successful in 21s
Nextcloud Server Tests / Nextcloud stable31 / PHP 8.3 (stable31, 8.3) (push) Successful in 18m25s
Nextcloud Server Tests / Nextcloud stable34 / PHP 8.2 (stable34, 8.2) (push) Successful in 17m8s
Nextcloud Server Tests / Nextcloud stable34 / PHP 8.3 (stable34, 8.3) (push) Successful in 16m23s
Nextcloud Server Tests / Nextcloud stable35 / PHP 8.3 (stable35, 8.3) (push) Successful in 17m24s
Nextcloud Server Tests / Nextcloud stable35 / PHP 8.4 (stable35, 8.4) (push) Successful in 16m42s
Nextcloud Server Tests / Nextcloud stable35 / PHP 8.5 (stable35, 8.5) (push) Successful in 17m34s
Nextcloud Server Tests / Nextcloud stable32 / PHP 8.2 (stable32, 8.2) (push) Successful in 17m26s
Nextcloud Server Tests / Nextcloud stable32 / PHP 8.3 (stable32, 8.3) (push) Successful in 16m45s
Nextcloud Server Tests / Nextcloud stable33 / PHP 8.2 (stable33, 8.2) (push) Successful in 17m2s
Nextcloud Server Tests / Nextcloud stable33 / PHP 8.3 (stable33, 8.3) (push) Successful in 16m36s
Release 0.8.5 with Nextcloud 35 support
2026-10-22 11:00:00 +07:00

128 lines
3.6 KiB
TypeScript

import { computed, ref, watch, type ComputedRef, type Ref } from 'vue'
import type { OnboardingState } from './useDashboard'
import {
getReleaseNotesEntries,
getReleaseNotesEntry,
normalizeReleaseVersion,
type ReleaseNotesEntry,
} from '../src/services/releaseNotes'
interface VersionOverlayDeps {
appVersion: Ref<string>
onboardingState: Ref<OnboardingState | null>
hasInitialLoad: Ref<boolean>
isBlocked: ComputedRef<boolean>
route: (name: 'persist') => string
postJson: (url: string, body: Record<string, unknown>) => Promise<any>
notifyError: (message: string) => void
}
export function useVersionOverlay(deps: VersionOverlayDeps) {
const isOpen = ref(false)
const isSaving = ref(false)
const selectedVersion = ref('')
const entries = computed(() => getReleaseNotesEntries().filter((entry) => entry.showInHistory !== false))
const currentVersion = computed(() => normalizeReleaseVersion(deps.appVersion.value))
const currentEntry = computed(() => getReleaseNotesEntry(currentVersion.value))
const selectedEntry = computed<ReleaseNotesEntry | null>(() => {
const version = normalizeReleaseVersion(selectedVersion.value)
return getReleaseNotesEntry(version)
})
const activeEntry = computed(() => selectedEntry.value ?? currentEntry.value)
const seenVersion = computed(() =>
normalizeReleaseVersion(deps.onboardingState.value?.releaseNotesSeenVersion ?? ''),
)
const shouldAutoOpen = computed(() =>
deps.hasInitialLoad.value
&& !deps.isBlocked.value
&& Boolean(currentEntry.value?.autoShow)
&& currentVersion.value !== ''
&& currentVersion.value !== seenVersion.value,
)
function openCurrent() {
if (!currentEntry.value) return
selectedVersion.value = currentEntry.value.version
isOpen.value = true
}
function openVersion(version: string) {
const entry = getReleaseNotesEntry(version)
if (!entry) return
selectedVersion.value = entry.version
isOpen.value = true
}
watch(
shouldAutoOpen,
(next) => {
if (next && !isOpen.value) {
openCurrent()
}
},
{ immediate: true },
)
watch(
() => deps.isBlocked.value,
(blocked) => {
if (blocked && shouldAutoOpen.value && activeEntry.value?.version === currentVersion.value) {
isOpen.value = false
} else if (!blocked && shouldAutoOpen.value && !isOpen.value) {
openCurrent()
}
},
)
async function markCurrentVersionSeen() {
if (!currentEntry.value) return
if (seenVersion.value === currentEntry.value.version) return
const nextState: OnboardingState = {
...(deps.onboardingState.value || {
completed: false,
version: 0,
strategy: '',
completed_at: '',
dashboardMode: 'standard',
}),
releaseNotesSeenVersion: currentEntry.value.version,
}
await deps.postJson(deps.route('persist'), { onboarding: nextState })
deps.onboardingState.value = nextState
}
async function closeOverlay() {
const shouldPersistCurrent = activeEntry.value?.version === currentVersion.value && Boolean(currentEntry.value)
isOpen.value = false
try {
if (shouldPersistCurrent) {
isSaving.value = true
await markCurrentVersionSeen()
}
isOpen.value = false
} catch (error) {
isOpen.value = true
console.error('[opsdash] release notes persist failed', error)
deps.notifyError('Failed to save release note state')
} finally {
isSaving.value = false
}
}
return {
isOpen,
isSaving,
entries,
currentVersion,
currentEntry,
activeEntry,
selectedVersion,
openCurrent,
openVersion,
closeOverlay,
}
}