update system permalinks to use id instead of name (#1231)

maintains backward compatibility with old permalinks
This commit is contained in:
henrygd
2025-10-05 14:18:00 -04:00
parent ae820d348e
commit d81e137291
7 changed files with 21 additions and 18 deletions

View File

@@ -65,7 +65,7 @@ export default memo(function CommandPalette({ open, setOpen }: { open: boolean;
<CommandItem <CommandItem
key={system.id} key={system.id}
onSelect={() => { onSelect={() => {
navigate(getPagePath($router, "system", { name: system.name })) navigate(getPagePath($router, "system", { id: system.id }))
setOpen(false) setOpen(false)
}} }}
> >

View File

@@ -2,7 +2,7 @@ import { createRouter } from "@nanostores/router"
const routes = { const routes = {
home: "/", home: "/",
system: `/system/:name`, system: `/system/:id`,
settings: `/settings/:name?`, settings: `/settings/:name?`,
forgot_password: `/forgot-password`, forgot_password: `/forgot-password`,
request_otp: `/request-otp`, request_otp: `/request-otp`,

View File

@@ -112,7 +112,7 @@ const ActiveAlerts = () => {
)} )}
</AlertDescription> </AlertDescription>
<Link <Link
href={getPagePath($router, "system", { name: systems[alert.system]?.name })} href={getPagePath($router, "system", { id: systems[alert.system]?.id })}
className="absolute inset-0 w-full h-full" className="absolute inset-0 w-full h-full"
aria-label="View system" aria-label="View system"
></Link> ></Link>

View File

@@ -27,6 +27,7 @@ import { getPbTimestamp, pb } from "@/lib/api"
import { ChartType, ConnectionType, connectionTypeLabels, Os, SystemStatus, Unit } from "@/lib/enums" import { ChartType, ConnectionType, connectionTypeLabels, Os, SystemStatus, Unit } from "@/lib/enums"
import { batteryStateTranslations } from "@/lib/i18n" import { batteryStateTranslations } from "@/lib/i18n"
import { import {
$allSystemsById,
$allSystemsByName, $allSystemsByName,
$chartTime, $chartTime,
$containerFilter, $containerFilter,
@@ -156,7 +157,7 @@ function dockerOrPodman(str: string, system: SystemRecord): string {
return str return str
} }
export default memo(function SystemDetail({ name }: { name: string }) { export default memo(function SystemDetail({ id }: { id: string }) {
const direction = useStore($direction) const direction = useStore($direction)
const { t } = useLingui() const { t } = useLingui()
const systems = useStore($systems) const systems = useStore($systems)
@@ -175,7 +176,6 @@ export default memo(function SystemDetail({ name }: { name: string }) {
const chartWrapRef = useRef<HTMLDivElement>(null) const chartWrapRef = useRef<HTMLDivElement>(null)
useEffect(() => { useEffect(() => {
document.title = `${name} / Beszel`
return () => { return () => {
if (!persistChartTime.current) { if (!persistChartTime.current) {
$chartTime.set($userSettings.get().chartTime) $chartTime.set($userSettings.get().chartTime)
@@ -185,15 +185,17 @@ export default memo(function SystemDetail({ name }: { name: string }) {
setContainerData([]) setContainerData([])
$containerFilter.set("") $containerFilter.set("")
} }
}, [name]) }, [id])
// find matching system and update when it changes // find matching system and update when it changes
useEffect(() => { useEffect(() => {
return subscribeKeys($allSystemsByName, [name], (newSystems) => { const store = $allSystemsById.get()[id] ? $allSystemsById : $allSystemsByName
const sys = newSystems[name] return subscribeKeys(store, [id], (newSystems) => {
const sys = newSystems[id]
document.title = `${sys?.name} / Beszel`
sys?.id && setSystem(sys) sys?.id && setSystem(sys)
}) })
}, [name]) }, [id])
// hide 1m chart time if system agent version is less than 0.13.0 // hide 1m chart time if system agent version is less than 0.13.0
useEffect(() => { useEffect(() => {
@@ -415,7 +417,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
) { ) {
return return
} }
const currentIndex = systems.findIndex((s) => s.name === name) const currentIndex = systems.findIndex((s) => s.id === id)
if (currentIndex === -1 || systems.length <= 1) { if (currentIndex === -1 || systems.length <= 1) {
return return
} }
@@ -424,18 +426,18 @@ export default memo(function SystemDetail({ name }: { name: string }) {
case "h": { case "h": {
const prevIndex = (currentIndex - 1 + systems.length) % systems.length const prevIndex = (currentIndex - 1 + systems.length) % systems.length
persistChartTime.current = true persistChartTime.current = true
return navigate(getPagePath($router, "system", { name: systems[prevIndex].name })) return navigate(getPagePath($router, "system", { id: systems[prevIndex].id }))
} }
case "ArrowRight": case "ArrowRight":
case "l": { case "l": {
const nextIndex = (currentIndex + 1) % systems.length const nextIndex = (currentIndex + 1) % systems.length
persistChartTime.current = true persistChartTime.current = true
return navigate(getPagePath($router, "system", { name: systems[nextIndex].name })) return navigate(getPagePath($router, "system", { id: systems[nextIndex].id }))
} }
} }
} }
return listen(document, "keyup", handleKeyUp) return listen(document, "keyup", handleKeyUp)
}, [name, systems]) }, [id, systems])
if (!system.id) { if (!system.id) {
return null return null

View File

@@ -77,6 +77,7 @@ export default function SystemsTableColumns(viewMode: "table" | "grid"): ColumnD
accessorKey: "name", accessorKey: "name",
id: "system", id: "system",
name: () => t`System`, name: () => t`System`,
sortingFn: (a, b) => a.original.name.localeCompare(b.original.name),
filterFn: (() => { filterFn: (() => {
let filterInput = "" let filterInput = ""
let filterInputLower = "" let filterInputLower = ""
@@ -110,7 +111,7 @@ export default function SystemsTableColumns(viewMode: "table" | "grid"): ColumnD
invertSorting: false, invertSorting: false,
Icon: ServerIcon, Icon: ServerIcon,
cell: (info) => { cell: (info) => {
const { name } = info.row.original const { name, id } = info.row.original
const longestName = useStore($longestSystemNameLen) const longestName = useStore($longestSystemNameLen)
return ( return (
<> <>
@@ -122,7 +123,7 @@ export default function SystemsTableColumns(viewMode: "table" | "grid"): ColumnD
</span> </span>
</span> </span>
<Link <Link
href={getPagePath($router, "system", { name })} href={getPagePath($router, "system", { id })}
className="inset-0 absolute size-full" className="inset-0 absolute size-full"
aria-label={name} aria-label={name}
></Link> ></Link>
@@ -279,7 +280,7 @@ export default function SystemsTableColumns(viewMode: "table" | "grid"): ColumnD
} }
return ( return (
<Link <Link
href={getPagePath($router, "system", { name: system.name })} href={getPagePath($router, "system", { id: system.id })}
className={cn( className={cn(
"flex gap-1.5 items-center md:pe-5 tabular-nums relative z-10", "flex gap-1.5 items-center md:pe-5 tabular-nums relative z-10",
viewMode === "table" && "ps-0.5" viewMode === "table" && "ps-0.5"

View File

@@ -486,7 +486,7 @@ const SystemCard = memo(
</div> </div>
</CardContent> </CardContent>
<Link <Link
href={getPagePath($router, "system", { name: row.original.name })} href={getPagePath($router, "system", { id: row.original.id })}
className="inset-0 absolute w-full h-full" className="inset-0 absolute w-full h-full"
> >
<span className="sr-only">{row.original.name}</span> <span className="sr-only">{row.original.name}</span>

View File

@@ -59,7 +59,7 @@ const App = memo(() => {
} else if (page.route === "home") { } else if (page.route === "home") {
return <Home /> return <Home />
} else if (page.route === "system") { } else if (page.route === "system") {
return <SystemDetail name={page.params.name} /> return <SystemDetail id={page.params.id} />
} else if (page.route === "settings") { } else if (page.route === "settings") {
return <Settings /> return <Settings />
} }