Update AppImage

This commit is contained in:
MacRimi
2025-11-18 20:56:15 +01:00
parent 7db8e18bcc
commit a2862f22f6
2 changed files with 96 additions and 48 deletions

View File

@@ -65,8 +65,14 @@ export function Settings() {
}, []) }, [])
const changeNetworkUnit = (unit: string) => { const changeNetworkUnit = (unit: string) => {
localStorage.setItem("proxmenux-network-unit", unit); const settings = { networkUnit: unit }
localStorage.setItem('unitsSettings', JSON.stringify(settings))
localStorage.setItem("proxmenux-network-unit", unit); // Keep legacy for backwards compatibility
setNetworkUnitSettings(unit); setNetworkUnitSettings(unit);
// Dispatch custom event to notify other components
window.dispatchEvent(new Event('unitsSettingsChanged'))
window.dispatchEvent(new Event('storage'))
}; };
const getUnitsSettings = () => { const getUnitsSettings = () => {

View File

@@ -163,6 +163,38 @@ export function SystemOverview() {
const [networkTotals, setNetworkTotals] = useState<{ received: number; sent: number }>({ received: 0, sent: 0 }) const [networkTotals, setNetworkTotals] = useState<{ received: number; sent: number }>({ received: 0, sent: 0 })
const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes")
useEffect(() => {
const getSettings = () => {
if (typeof window === 'undefined') return { networkUnit: 'Bytes' as const }
try {
const settings = window.localStorage.getItem('unitsSettings')
if (settings) {
const parsed = JSON.parse(settings)
return { networkUnit: parsed.networkUnit || 'Bytes' }
}
} catch (e) {
console.error('[v0] Error reading units settings:', e)
}
return { networkUnit: 'Bytes' as const }
}
const settings = getSettings()
setNetworkUnit(settings.networkUnit as "Bytes" | "Bits")
const handleStorageChange = () => {
const settings = getSettings()
setNetworkUnit(settings.networkUnit as "Bytes" | "Bits")
}
window.addEventListener('storage', handleStorageChange)
window.addEventListener('unitsSettingsChanged', handleStorageChange)
return () => {
window.removeEventListener('storage', handleStorageChange)
window.removeEventListener('unitsSettingsChanged', handleStorageChange)
}
}, [])
useEffect(() => { useEffect(() => {
const fetchAllData = async () => { const fetchAllData = async () => {
const [systemResult, vmResult, storageResults, networkResult] = await Promise.all([ const [systemResult, vmResult, storageResults, networkResult] = await Promise.all([
@@ -311,13 +343,19 @@ export function SystemOverview() {
const formatNetworkTraffic = (sizeInGB: number, unit: "Bytes" | "Bits" = "Bytes"): string => { const formatNetworkTraffic = (sizeInGB: number, unit: "Bytes" | "Bits" = "Bytes"): string => {
if (unit === "Bits") { if (unit === "Bits") {
const sizeInGb = sizeInGB * 8 const sizeInBits = sizeInGB * 8
if (sizeInGb < 1) { if (sizeInBits < 1024) {
return `${(sizeInGb * 1024).toFixed(1)} Mb` return `${sizeInBits.toFixed(1)} b`
} else if (sizeInGb > 999) { } else if (sizeInBits < 1024 ** 2) {
return `${(sizeInGb / 1024).toFixed(2)} Tb` return `${(sizeInBits / 1024).toFixed(1)} Kb`
} else if (sizeInBits < 1024 ** 3) {
return `${(sizeInBits / 1024 ** 2).toFixed(1)} Mb`
} else if (sizeInBits < 1024 ** 4) {
return `${(sizeInBits / 1024 ** 3).toFixed(2)} Gb`
} else if (sizeInBits < 1024 ** 5) {
return `${(sizeInBits / 1024 ** 4).toFixed(2)} Tb`
} else { } else {
return `${sizeInGb.toFixed(2)} Gb` return `${(sizeInBits / 1024 ** 5).toFixed(2)} Pb`
} }
} else { } else {
return formatStorage(sizeInGB) return formatStorage(sizeInGB)
@@ -427,26 +465,6 @@ export function SystemOverview() {
</CardContent> </CardContent>
</Card> </Card>
<Card className="bg-card border-border">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground">Temperature</CardTitle>
<Thermometer className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-xl lg:text-2xl font-bold text-foreground">
{systemData.temperature === 0 ? "N/A" : `${systemData.temperature}°C`}
</div>
<div className="flex items-center mt-2">
<Badge variant="outline" className={tempStatus.color}>
{tempStatus.status}
</Badge>
</div>
<p className="text-xs text-muted-foreground mt-2">
{systemData.temperature === 0 ? "No sensor available" : "Live temperature reading"}
</p>
</CardContent>
</Card>
<Card className="bg-card border-border"> <Card className="bg-card border-border">
<CardHeader> <CardHeader>
<CardTitle className="text-foreground flex items-center"> <CardTitle className="text-foreground flex items-center">
@@ -481,6 +499,28 @@ export function SystemOverview() {
)} )}
</CardContent> </CardContent>
</Card> </Card>
<Card className="bg-card border-border">
<CardHeader>
<CardTitle className="text-foreground flex items-center">
<Thermometer className="h-5 w-5 mr-2" />
Temperature
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-xl lg:text-2xl font-bold text-foreground">
{systemData.temperature === 0 ? "N/A" : `${systemData.temperature}°C`}
</div>
<div className="flex items-center mt-2">
<Badge variant="outline" className={tempStatus.color}>
{tempStatus.status}
</Badge>
</div>
<p className="text-xs text-muted-foreground mt-2">
{systemData.temperature === 0 ? "No sensor available" : "Live temperature reading"}
</p>
</CardContent>
</Card>
</div> </div>
<NodeMetricsCharts /> <NodeMetricsCharts />
@@ -615,6 +655,7 @@ export function SystemOverview() {
<Network className="h-5 w-5 mr-2" /> <Network className="h-5 w-5 mr-2" />
Network Overview Network Overview
</div> </div>
<div className="flex gap-2">
<Select value={networkTimeframe} onValueChange={setNetworkTimeframe}> <Select value={networkTimeframe} onValueChange={setNetworkTimeframe}>
<SelectTrigger className="w-28 h-8 text-xs"> <SelectTrigger className="w-28 h-8 text-xs">
<SelectValue /> <SelectValue />
@@ -636,6 +677,7 @@ export function SystemOverview() {
<SelectItem value="Bits">Bits</SelectItem> <SelectItem value="Bits">Bits</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
</div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>