Files
summercms/admin/src/main.ts
Jakub Zych 291b18fb1e feat(boardwalk): expose the admin build id and show a reload banner when a new build is deployed (quick-261028-rqb)
- boardwalk.BuildID hashes the dist tree plus the binary's build info once
  per handler; X-Summer-Build on every response, {prefix}/build.json and the
  summer-admin-build meta carry it
- the SPA reads the booted build, re-checks on focus, visibility and every
  5 minutes, and shows UpdateBanner on a different build
2026-10-28 21:19:36 +01:00

47 lines
2.1 KiB
TypeScript

import { createApp } from 'vue'
import App from './App.vue'
import { createAdminRouter } from './app/router'
import { onUnauthorized } from './api/client'
import { startBuildWatch } from './app/buildUpdate'
import { loadFieldTypes } from './app/fieldTypes'
import { loadStrings } from './app/i18n'
import { expireSession, me } from './state/useAuth'
import { loadNavigation } from './state/useNavigation'
import { applyTheme, cachedLocale, cachedTheme } from './state/usePreferences'
import { loadSettings } from './state/useSettings'
import './styles/main.css'
async function boot(): Promise<void> {
// The last theme choice (system unless the admin picked light or dark) is
// applied before the first await, so nothing renders in the wrong theme;
// me() then applies the admin's stored preference.
applyTheme(cachedTheme())
// Boot order (research Pattern 7): the public strings bundle first, so the
// login screen is translated, then the session, then navigation and the
// plugin field types.
// The cached admin language picks the bundle's locale; me() reloads the
// strings when the stored preference differs.
await loadStrings(cachedLocale() || undefined).catch(() => undefined)
// A 401 here only means "not signed in"; the router guard sends the
// visitor to the login route with the requested path as redirect.
const user = await me().catch(() => null)
if (user) {
// Plugin field types load once per session: their scripts define the
// elements any controller's form may use, their styles stay enabled.
await Promise.all([loadNavigation().catch(() => []), loadSettings().catch(() => []), loadFieldTypes()])
}
const router = createAdminRouter()
// A session that cannot be recovered ends here: the profile and every
// stored list query are cleared before the login screen shows (T-16.1-03).
onUnauthorized(() => expireSession(router))
const app = createApp(App)
app.use(router)
await router.isReady()
app.mount('#app')
// The new-version check; it stays off when the served index carries no
// build (the dev server).
startBuildWatch()
}
void boot()