Use URL-based routing instead of local state
This commit is contained in:
parent
68274d8651
commit
45b1903e6b
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect } from 'hono/jsx'
|
||||
import { openAppSelectorModal } from '../modals'
|
||||
import { navigate } from '../router'
|
||||
import { dashboardTab, isNarrow, setDashboardTab } from '../state'
|
||||
import { dashboardTab, isNarrow } from '../state'
|
||||
import {
|
||||
AppSelectorChevron,
|
||||
DashboardContainer,
|
||||
|
|
@ -30,8 +30,7 @@ export function DashboardLanding({ render }: { render: () => void }) {
|
|||
}
|
||||
|
||||
const switchTab = (tab: typeof dashboardTab) => {
|
||||
setDashboardTab(tab)
|
||||
render()
|
||||
navigate(tab === 'urls' ? '/' : `/${tab}`)
|
||||
if (tab === 'logs') scrollLogsToBottom()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { App } from '../../shared/types'
|
||||
import { apps, getSelectedTab, setSelectedTab } from '../state'
|
||||
import { navigate } from '../router'
|
||||
import { apps, getSelectedTab } from '../state'
|
||||
import { Tab, TabBar } from '../styles'
|
||||
import { resetToolIframe } from '../tool-iframes'
|
||||
|
||||
|
|
@ -12,8 +13,7 @@ export function Nav({ app, render }: { app: App; render: () => void }) {
|
|||
resetToolIframe(tab, app.name)
|
||||
return
|
||||
}
|
||||
setSelectedTab(app.name, tab)
|
||||
render()
|
||||
navigate(tab === 'overview' ? `/app/${app.name}` : `/app/${app.name}/${tab}`)
|
||||
}
|
||||
|
||||
// Find all tools
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { setCurrentView, setSelectedApp } from './state'
|
||||
import { setCurrentView, setDashboardTab, setSelectedApp, setSelectedTab } from './state'
|
||||
|
||||
let _render: () => void
|
||||
|
||||
|
|
@ -31,14 +31,27 @@ function route() {
|
|||
const path = location.pathname
|
||||
|
||||
if (path.startsWith('/app/')) {
|
||||
const name = decodeURIComponent(path.slice(5))
|
||||
const rest = decodeURIComponent(path.slice(5))
|
||||
const slashIdx = rest.indexOf('/')
|
||||
const name = slashIdx === -1 ? rest : rest.slice(0, slashIdx)
|
||||
const tab = slashIdx === -1 ? 'overview' : rest.slice(slashIdx + 1)
|
||||
setSelectedApp(name)
|
||||
setSelectedTab(name, tab)
|
||||
setCurrentView('dashboard')
|
||||
} else if (path === '/settings') {
|
||||
setSelectedApp(null)
|
||||
setCurrentView('settings')
|
||||
} else if (path === '/logs') {
|
||||
setSelectedApp(null)
|
||||
setDashboardTab('logs')
|
||||
setCurrentView('dashboard')
|
||||
} else if (path === '/metrics') {
|
||||
setSelectedApp(null)
|
||||
setDashboardTab('metrics')
|
||||
setCurrentView('dashboard')
|
||||
} else {
|
||||
setSelectedApp(null)
|
||||
setDashboardTab('urls')
|
||||
setCurrentView('dashboard')
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,19 +7,18 @@ export let currentView: 'dashboard' | 'settings' = 'dashboard'
|
|||
export let isNarrow: boolean = window.matchMedia('(max-width: 768px)').matches
|
||||
export let selectedApp: string | null = null
|
||||
export let sidebarCollapsed: boolean = localStorage.getItem('sidebarCollapsed') === 'true'
|
||||
export let dashboardTab: DashboardTab = (localStorage.getItem('dashboardTab') as DashboardTab) || 'urls'
|
||||
export let dashboardTab: DashboardTab = 'urls'
|
||||
export let sidebarSection: 'apps' | 'tools' = (localStorage.getItem('sidebarSection') as 'apps' | 'tools') || 'apps'
|
||||
|
||||
// Server state (from SSE)
|
||||
export let apps: App[] = []
|
||||
|
||||
// Tab state
|
||||
export let appTabs: Record<string, string> = JSON.parse(localStorage.getItem('appTabs') || '{}')
|
||||
export let appTabs: Record<string, string> = {}
|
||||
|
||||
// State setters
|
||||
export function setDashboardTab(tab: DashboardTab) {
|
||||
dashboardTab = tab
|
||||
localStorage.setItem('dashboardTab', tab)
|
||||
}
|
||||
|
||||
export function setCurrentView(view: 'dashboard' | 'settings') {
|
||||
|
|
@ -54,5 +53,4 @@ export const getSelectedTab = (appName: string | null) =>
|
|||
export function setSelectedTab(appName: string | null, tab: string) {
|
||||
if (!appName) return
|
||||
appTabs[appName] = tab
|
||||
localStorage.setItem('appTabs', JSON.stringify(appTabs))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,10 @@ app.get('/dist/:file', async c => {
|
|||
})
|
||||
|
||||
// SPA routes — serve the shell for all client-side paths
|
||||
app.get('/app/:name/:tab', c => c.html(<Shell />))
|
||||
app.get('/app/:name', c => c.html(<Shell />))
|
||||
app.get('/logs', c => c.html(<Shell />))
|
||||
app.get('/metrics', c => c.html(<Shell />))
|
||||
app.get('/settings', c => c.html(<Shell />))
|
||||
|
||||
cleanupStalePublishers()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user