mirror of
https://github.com/henrygd/beszel.git
synced 2026-03-25 15:06:17 +01:00
Compare commits
17 Commits
79616e1662
...
l10n_main_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24feffcc92 | ||
|
|
9586b461d8 | ||
|
|
78936b1481 | ||
|
|
5b6af761f1 | ||
|
|
29b914a43b | ||
|
|
4a86357d64 | ||
|
|
b65f011222 | ||
|
|
f836609552 | ||
|
|
b2a3c52005 | ||
|
|
6e2277ead1 | ||
|
|
cffc3d8569 | ||
|
|
aa8b3711d7 | ||
|
|
1fb0b25988 | ||
|
|
04600d83cc | ||
|
|
5d8906c9b2 | ||
|
|
daac287b9d | ||
|
|
d526ea61a9 |
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -91,8 +91,8 @@ func (c *ConnectionManager) Start(serverOptions ServerOptions) error {
|
||||
c.eventChan = make(chan ConnectionEvent, 1)
|
||||
|
||||
// signal handling for shutdown
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
sigCtx, stopSignals := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stopSignals()
|
||||
|
||||
c.startWsTicker()
|
||||
c.connect()
|
||||
@@ -109,8 +109,8 @@ func (c *ConnectionManager) Start(serverOptions ServerOptions) error {
|
||||
_ = c.startWebSocketConnection()
|
||||
case <-healthTicker:
|
||||
_ = health.Update()
|
||||
case <-sigChan:
|
||||
slog.Info("Shutting down")
|
||||
case <-sigCtx.Done():
|
||||
slog.Info("Shutting down", "cause", context.Cause(sigCtx))
|
||||
_ = c.agent.StopServer()
|
||||
c.closeWebSocket()
|
||||
return health.CleanUp()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -89,10 +89,7 @@ func getPerCoreCpuUsage(cacheTimeMs uint16) (system.Uint8Slice, error) {
|
||||
lastTimes := lastPerCoreCpuTimes[cacheTimeMs]
|
||||
|
||||
// Limit to the number of cores available in both samples
|
||||
length := len(perCoreTimes)
|
||||
if len(lastTimes) < length {
|
||||
length = len(lastTimes)
|
||||
}
|
||||
length := min(len(lastTimes), len(perCoreTimes))
|
||||
|
||||
usage := make([]uint8, length)
|
||||
for i := 0; i < length; i++ {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ func (a *Agent) initializeDiskInfo() {
|
||||
|
||||
// Add EXTRA_FILESYSTEMS env var values to fsStats
|
||||
if extraFilesystems, exists := GetEnv("EXTRA_FILESYSTEMS"); exists {
|
||||
for _, fsEntry := range strings.Split(extraFilesystems, ",") {
|
||||
for fsEntry := range strings.SplitSeq(extraFilesystems, ",") {
|
||||
// Parse custom name from format: device__customname
|
||||
fs, customName := parseFilesystemEntry(fsEntry)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -103,10 +103,8 @@ func (gm *GPUManager) updateAmdGpuData(cardPath string) bool {
|
||||
|
||||
// Read all sysfs values first (no lock needed - these can be slow)
|
||||
usage, usageErr := readSysfsFloat(filepath.Join(devicePath, "gpu_busy_percent"))
|
||||
vramUsed, memUsedErr := readSysfsFloat(filepath.Join(devicePath, "mem_info_vram_used"))
|
||||
vramTotal, _ := readSysfsFloat(filepath.Join(devicePath, "mem_info_vram_total"))
|
||||
memUsed := vramUsed
|
||||
memTotal := vramTotal
|
||||
memUsed, memUsedErr := readSysfsFloat(filepath.Join(devicePath, "mem_info_vram_used"))
|
||||
memTotal, _ := readSysfsFloat(filepath.Join(devicePath, "mem_info_vram_total"))
|
||||
// if gtt is present, add it to the memory used and total (https://github.com/henrygd/beszel/issues/1569#issuecomment-3837640484)
|
||||
if gttUsed, err := readSysfsFloat(filepath.Join(devicePath, "mem_info_gtt_used")); err == nil && gttUsed > 0 {
|
||||
if gttTotal, err := readSysfsFloat(filepath.Join(devicePath, "mem_info_gtt_total")); err == nil {
|
||||
@@ -243,7 +241,10 @@ func getCachedAmdgpuName(deviceID, revisionID string) (name string, found bool,
|
||||
|
||||
// normalizeAmdgpuName trims standard suffixes from AMDGPU product names.
|
||||
func normalizeAmdgpuName(name string) string {
|
||||
return strings.TrimSuffix(strings.TrimSpace(name), " Graphics")
|
||||
for _, suffix := range []string{" Graphics", " Series"} {
|
||||
name = strings.TrimSuffix(name, suffix)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// cacheAmdgpuName stores a resolved AMDGPU name in the lookup cache.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package health
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -476,7 +476,7 @@ func (sm *SmartManager) CollectSmart(deviceInfo *DeviceInfo) error {
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
// Check if device is in standby (exit status 2)
|
||||
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 2 {
|
||||
if exitErr, ok := errors.AsType[*exec.ExitError](err); ok && exitErr.ExitCode() == 2 {
|
||||
if hasExistingData {
|
||||
// Device is in standby and we have cached data, keep using cache
|
||||
return nil
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package agent
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package alerts_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package alerts_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package alerts_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package alerts_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package alerts
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ func ColorPrint(color, text string) {
|
||||
fmt.Println(color + text + colorReset)
|
||||
}
|
||||
|
||||
func ColorPrintf(color, format string, args ...interface{}) {
|
||||
func ColorPrintf(color, format string, args ...any) {
|
||||
fmt.Printf(color+format+colorReset+"\n", args...)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package hub
|
||||
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -35,6 +35,26 @@ func createTestHub(t testing.TB) (*Hub, *pbtests.TestApp, error) {
|
||||
return NewHub(testApp), testApp, nil
|
||||
}
|
||||
|
||||
// cleanupTestHub stops background system goroutines before tearing down the app.
|
||||
func cleanupTestHub(hub *Hub, testApp *pbtests.TestApp) {
|
||||
if hub != nil {
|
||||
sm := hub.GetSystemManager()
|
||||
sm.RemoveAllSystems()
|
||||
// Give updater goroutines a brief window to observe cancellation before DB teardown.
|
||||
for range 20 {
|
||||
if sm.GetSystemCount() == 0 {
|
||||
break
|
||||
}
|
||||
runtime.Gosched()
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
}
|
||||
if testApp != nil {
|
||||
testApp.Cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create a test record
|
||||
func createTestRecord(app core.App, collection string, data map[string]any) (*core.Record, error) {
|
||||
col, err := app.FindCachedCollectionByNameOrId(collection)
|
||||
@@ -64,7 +84,7 @@ func TestValidateAgentHeaders(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -145,7 +165,7 @@ func TestGetAllFingerprintRecordsByToken(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
@@ -235,7 +255,7 @@ func TestSetFingerprint(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
@@ -315,7 +335,7 @@ func TestCreateSystemFromAgentData(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
@@ -425,7 +445,7 @@ func TestUniversalTokenFlow(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(nil, testApp)
|
||||
|
||||
// Create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
@@ -493,7 +513,7 @@ func TestAgentConnect(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
@@ -652,7 +672,7 @@ func TestHandleAgentConnect(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
@@ -737,7 +757,7 @@ func TestAgentWebSocketIntegration(t *testing.T) {
|
||||
// Create hub and test app
|
||||
hub, testApp, err := createTestHub(t)
|
||||
require.NoError(t, err)
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Get the hub's SSH key
|
||||
hubSigner, err := hub.GetSSHKey("")
|
||||
@@ -942,6 +962,8 @@ func TestAgentWebSocketIntegration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
|
||||
// Verify fingerprint state by re-reading the specific record
|
||||
updatedFingerprintRecord, err := testApp.FindRecordById("fingerprints", fingerprintRecord.Id)
|
||||
require.NoError(t, err)
|
||||
@@ -976,7 +998,7 @@ func TestMultipleSystemsWithSameUniversalToken(t *testing.T) {
|
||||
// Create hub and test app
|
||||
hub, testApp, err := createTestHub(t)
|
||||
require.NoError(t, err)
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Get the hub's SSH key
|
||||
hubSigner, err := hub.GetSSHKey("")
|
||||
@@ -1144,6 +1166,8 @@ func TestMultipleSystemsWithSameUniversalToken(t *testing.T) {
|
||||
assert.Equal(t, systemCount, systemsAfterCount, "Total system count should remain the same")
|
||||
}
|
||||
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
|
||||
// Verify that a fingerprint record exists for this fingerprint
|
||||
fingerprints, err := testApp.FindRecordsByFilter("fingerprints", "token = {:token} && fingerprint = {:fingerprint}", "", -1, 0, map[string]any{
|
||||
"token": universalToken,
|
||||
@@ -1176,7 +1200,7 @@ func TestPermanentUniversalTokenFromDB(t *testing.T) {
|
||||
// Create hub and test app
|
||||
hub, testApp, err := createTestHub(t)
|
||||
require.NoError(t, err)
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Get the hub's SSH key
|
||||
hubSigner, err := hub.GetSSHKey("")
|
||||
@@ -1273,7 +1297,7 @@ verify:
|
||||
func TestFindOrCreateSystemForToken(t *testing.T) {
|
||||
hub, testApp, err := createTestHub(t)
|
||||
require.NoError(t, err)
|
||||
defer testApp.Cleanup()
|
||||
defer cleanupTestHub(hub, testApp)
|
||||
|
||||
// Create test user
|
||||
userRecord, err := createTestUser(testApp)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package config_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package expirymap
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package heartbeat_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package hub_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package hub
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build !testing
|
||||
// +build !testing
|
||||
|
||||
package systems
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package systems_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package systems
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package ws
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package ws
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package ws
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package records_test
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
package records
|
||||
|
||||
|
||||
@@ -656,14 +656,14 @@ function DiskSheet({
|
||||
</Tooltip>
|
||||
</SheetDescription>
|
||||
</SheetHeader>
|
||||
<div className="flex-1 overflow-auto p-4 flex flex-col gap-4">
|
||||
<div className="flex-1 overflow-hidden p-4 flex flex-col gap-4">
|
||||
{isLoading ? (
|
||||
<div className="flex justify-center py-8">
|
||||
<LoaderCircleIcon className="animate-spin size-10 opacity-60" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<Alert className="pb-3">
|
||||
<Alert className="pb-3 shrink-0">
|
||||
{status === "PASSED" ? <CheckCircle2Icon className="size-4" /> : <XCircleIcon className="size-4" />}
|
||||
<AlertTitle>
|
||||
<Trans>S.M.A.R.T. Self-Test</Trans>: {status}
|
||||
@@ -675,9 +675,9 @@ function DiskSheet({
|
||||
)}
|
||||
</Alert>
|
||||
{smartAttributes.length > 0 ? (
|
||||
<div className="rounded-md border overflow-auto">
|
||||
<div className="rounded-md border min-h-0 flex flex-col">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableHeader className="sticky top-0 z-10">
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
|
||||
@@ -33,7 +33,6 @@ import {
|
||||
decimalString,
|
||||
formatBytes,
|
||||
formatTemperature,
|
||||
getMeterState,
|
||||
parseSemVer,
|
||||
secondsToUptimeString,
|
||||
} from "@/lib/utils"
|
||||
@@ -81,6 +80,10 @@ const STATUS_COLORS = {
|
||||
[SystemStatus.Pending]: "bg-yellow-500",
|
||||
} as const
|
||||
|
||||
function getMeterStateByThresholds(value: number, warn = 65, crit = 90): MeterState {
|
||||
return value >= crit ? MeterState.Crit : value >= warn ? MeterState.Warn : MeterState.Good
|
||||
}
|
||||
|
||||
/**
|
||||
* @param viewMode - "table" or "grid"
|
||||
* @returns - Column definitions for the systems table
|
||||
@@ -209,6 +212,7 @@ export function SystemsTableColumns(viewMode: "table" | "grid"): ColumnDef<Syste
|
||||
header: sortableHeader,
|
||||
cell(info: CellContext<SystemRecord, unknown>) {
|
||||
const { info: sysInfo, status } = info.row.original
|
||||
const { colorWarn = 65, colorCrit = 90 } = useStore($userSettings, { keys: ["colorWarn", "colorCrit"] })
|
||||
// agent version
|
||||
const { minor, patch } = parseSemVer(sysInfo.v)
|
||||
let loadAverages = sysInfo.la
|
||||
@@ -224,7 +228,7 @@ export function SystemsTableColumns(viewMode: "table" | "grid"): ColumnDef<Syste
|
||||
}
|
||||
|
||||
const normalizedLoad = max / (sysInfo.t ?? 1)
|
||||
const threshold = getMeterState(normalizedLoad * 100)
|
||||
const threshold = getMeterStateByThresholds(normalizedLoad * 100, colorWarn, colorCrit)
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-[.35em] w-full tabular-nums tracking-tight">
|
||||
@@ -463,8 +467,9 @@ function sortableHeader(context: HeaderContext<SystemRecord, unknown>) {
|
||||
}
|
||||
|
||||
function TableCellWithMeter(info: CellContext<SystemRecord, unknown>) {
|
||||
const { colorWarn = 65, colorCrit = 90 } = useStore($userSettings, { keys: ["colorWarn", "colorCrit"] })
|
||||
const val = Number(info.getValue()) || 0
|
||||
const threshold = getMeterState(val)
|
||||
const threshold = getMeterStateByThresholds(val, colorWarn, colorCrit)
|
||||
const meterClass = cn(
|
||||
"h-full",
|
||||
(info.row.original.status !== SystemStatus.Up && STATUS_COLORS.paused) ||
|
||||
@@ -483,6 +488,7 @@ function TableCellWithMeter(info: CellContext<SystemRecord, unknown>) {
|
||||
}
|
||||
|
||||
function DiskCellWithMultiple(info: CellContext<SystemRecord, unknown>) {
|
||||
const { colorWarn = 65, colorCrit = 90 } = useStore($userSettings, { keys: ["colorWarn", "colorCrit"] })
|
||||
const { info: sysInfo, status, id } = info.row.original
|
||||
const extraFs = Object.entries(sysInfo.efs ?? {})
|
||||
|
||||
@@ -496,7 +502,7 @@ function DiskCellWithMultiple(info: CellContext<SystemRecord, unknown>) {
|
||||
extraFs.sort((a, b) => b[1] - a[1])
|
||||
|
||||
function getIndicatorColor(pct: number) {
|
||||
const threshold = getMeterState(pct)
|
||||
const threshold = getMeterStateByThresholds(pct, colorWarn, colorCrit)
|
||||
return (
|
||||
(status !== SystemStatus.Up && STATUS_COLORS.paused) ||
|
||||
(threshold === MeterState.Good && STATUS_COLORS.up) ||
|
||||
@@ -514,7 +520,9 @@ function DiskCellWithMultiple(info: CellContext<SystemRecord, unknown>) {
|
||||
const extraDiskIndicators =
|
||||
status !== SystemStatus.Up
|
||||
? []
|
||||
: [...new Set(extraFs.map(([, pct]) => getMeterState(pct)))].sort().map((state) => stateColors[state])
|
||||
: [...new Set(extraFs.map(([, pct]) => getMeterStateByThresholds(pct, colorWarn, colorCrit)))]
|
||||
.sort()
|
||||
.map((state) => stateColors[state])
|
||||
|
||||
return (
|
||||
<Tooltip>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useEffect, useState } from "react"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { toast } from "@/components/ui/use-toast"
|
||||
import type { ChartTimeData, FingerprintRecord, SemVer, SystemRecord } from "@/types"
|
||||
import { HourFormat, MeterState, Unit } from "./enums"
|
||||
import { HourFormat, Unit } from "./enums"
|
||||
import { $copyContent, $userSettings } from "./stores"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
@@ -210,7 +210,6 @@ export function useBrowserStorage<T>(key: string, defaultValue: T, storageInterf
|
||||
const [value, setValue] = useState(() => {
|
||||
return getStorageValue(key, defaultValue, storageInterface)
|
||||
})
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: storageInterface won't change
|
||||
useEffect(() => {
|
||||
storageInterface?.setItem(key, JSON.stringify(value))
|
||||
}, [key, value])
|
||||
@@ -394,12 +393,6 @@ export function compareSemVer(a: SemVer, b: SemVer) {
|
||||
return a.patch - b.patch
|
||||
}
|
||||
|
||||
/** Get meter state from 0-100 value. Used for color coding meters. */
|
||||
export function getMeterState(value: number): MeterState {
|
||||
const { colorWarn = 65, colorCrit = 90 } = $userSettings.get()
|
||||
return value >= colorCrit ? MeterState.Crit : value >= colorWarn ? MeterState.Warn : MeterState.Good
|
||||
}
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: any is used to allow any function to be passed in
|
||||
export function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void {
|
||||
let timeout: ReturnType<typeof setTimeout>
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: bg\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-31 21:16\n"
|
||||
"PO-Revision-Date: 2026-02-25 11:49\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Bulgarian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -357,7 +357,7 @@ msgstr "Провери log-овете за повече информация."
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Check your monitoring service"
|
||||
msgstr "Проверете вашата услуга за мониторинг"
|
||||
msgstr "Проверете мониторинг услугата си"
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Check your notification service"
|
||||
@@ -937,7 +937,6 @@ msgstr "Средно натоварване"
|
||||
msgid "Load state"
|
||||
msgstr "Състояние на зареждане"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "Зареждане..."
|
||||
@@ -1378,7 +1377,7 @@ msgstr "Избери {foo}"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Send a single heartbeat ping to verify your endpoint is working."
|
||||
msgstr "Изпратете единичен heartbeat пинг, за да проверите дали вашата крайна точка работи."
|
||||
msgstr "Изпратете единичен heartbeat пинг, за да се уверите, че крайната Ви точка работи."
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Send periodic outbound pings to an external monitoring service so you can monitor Beszel without exposing it to the internet."
|
||||
@@ -1410,7 +1409,7 @@ msgstr "Задайте процентни прагове за цветовете
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Set the following environment variables on your Beszel hub to enable heartbeat monitoring:"
|
||||
msgstr "Задайте следните променливи на средата на вашия Beszel hub, за да активирате мониторинга на heartbeat:"
|
||||
msgstr "Задайте следните променливи на средата на вашия Beszel hub, за да активирате heartbeat мониторинг:"
|
||||
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/command-palette.tsx
|
||||
@@ -1800,7 +1799,7 @@ msgstr "Webhook / Пуш нотификации"
|
||||
|
||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||
msgid "When enabled, this token allows agents to self-register without prior system creation."
|
||||
msgstr "Когато е активиран, този символ позволява на агентите да се регистрират сами без предварително създаване на система."
|
||||
msgstr "Когато е активиран, този токен позволява на агентите да се регистрират сами без предварително създаване на система."
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "When using POST, each heartbeat includes a JSON payload with system status summary, list of down systems, and triggered alerts."
|
||||
@@ -1835,3 +1834,4 @@ msgstr "Да"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "Настройките за потребителя ти са обновени."
|
||||
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Odeslání"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Doba provozu"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-31 21:16\n"
|
||||
"PO-Revision-Date: 2026-03-14 20:37\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -236,7 +236,7 @@ msgstr "Bandbreite"
|
||||
#. Battery label in systems table header
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Bat"
|
||||
msgstr "Bat"
|
||||
msgstr "Batt"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/lib/alerts.ts
|
||||
@@ -937,7 +937,6 @@ msgstr "Systemlast"
|
||||
msgid "Load state"
|
||||
msgstr "Ladezustand"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "Lädt..."
|
||||
@@ -1178,7 +1177,7 @@ msgstr "Prozentsatz der Zeit in jedem Zustand"
|
||||
|
||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||
msgid "Permanent"
|
||||
msgstr "Permanent"
|
||||
msgstr "Dauerhaft"
|
||||
|
||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||
msgid "Persistence"
|
||||
@@ -1835,3 +1834,4 @@ msgstr "Ja"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "Deine Benutzereinstellungen wurden aktualisiert."
|
||||
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Cargar"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Tiempo de actividad"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Téléverser"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Temps de fonctionnement"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Otpremi"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Vrijeme rada"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Carica"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Tempo di attività"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "업로드"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "가동 시간"
|
||||
msgstr "가동시간"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: nl\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-02-19 19:40\n"
|
||||
"PO-Revision-Date: 2026-02-24 11:37\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Dutch\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -836,7 +836,7 @@ msgstr "Gezondheid"
|
||||
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Heartbeat"
|
||||
msgstr "Heartbeat"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Heartbeat Monitoring"
|
||||
@@ -884,7 +884,7 @@ msgstr "Inactief"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Interval"
|
||||
msgstr "Interval"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/login/auth-form.tsx
|
||||
msgid "Invalid email address."
|
||||
@@ -937,7 +937,6 @@ msgstr "Gem. Belasting"
|
||||
msgid "Load state"
|
||||
msgstr "Laadstatus"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "Laden..."
|
||||
@@ -1835,3 +1834,4 @@ msgstr "Ja"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "Je gebruikersinstellingen zijn bijgewerkt."
|
||||
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Wysyłanie"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Czas pracy"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Carregar"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Tempo de Atividade"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: ru\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-31 21:16\n"
|
||||
"PO-Revision-Date: 2026-02-21 09:46\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Russian\n"
|
||||
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
||||
@@ -937,7 +937,6 @@ msgstr "Ср. загрузка"
|
||||
msgid "Load state"
|
||||
msgstr "Состояние загрузки"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "Загрузка..."
|
||||
@@ -1835,3 +1834,4 @@ msgstr "Да"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "Ваши настройки пользователя были обновлены."
|
||||
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Naloži"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Čas delovanja"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: sr\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-02-03 15:27\n"
|
||||
"PO-Revision-Date: 2026-02-23 15:11\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Serbian (Cyrillic)\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
@@ -836,7 +836,7 @@ msgstr "Здравље"
|
||||
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Heartbeat"
|
||||
msgstr "Heartbeat"
|
||||
msgstr "Оркуцај"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Heartbeat Monitoring"
|
||||
@@ -884,7 +884,7 @@ msgstr "Неактивно"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Interval"
|
||||
msgstr "Interval"
|
||||
msgstr "Интервал"
|
||||
|
||||
#: src/components/login/auth-form.tsx
|
||||
msgid "Invalid email address."
|
||||
@@ -937,7 +937,6 @@ msgstr "Просечно опт."
|
||||
msgid "Load state"
|
||||
msgstr "Стање учитавања"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "Учитавање..."
|
||||
@@ -1835,3 +1834,4 @@ msgstr "Да"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "Ваша корисничка подешавања су ажурирана."
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: tr\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-31 21:16\n"
|
||||
"PO-Revision-Date: 2026-03-02 13:16\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Turkish\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -143,7 +143,7 @@ msgstr "Sonra"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "After setting the environment variables, restart your Beszel hub for changes to take effect."
|
||||
msgstr "Ortam değişkenlerini ayarladıktan sonra, değişikliklerin etkili olması için Beszel hub'ınızı yeniden başlatın."
|
||||
msgstr "Ortam değişkenlerini ayarladıktan sonra, değişikliklerin etkili olması için Beszel Hub'ınızı yeniden başlatın."
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Agent"
|
||||
@@ -466,7 +466,7 @@ msgstr "YAML'ı kopyala"
|
||||
#: src/components/systemd-table/systemd-table-columns.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "CPU"
|
||||
msgstr "CPU"
|
||||
msgstr "İşlemci"
|
||||
|
||||
#: src/components/routes/system/cpu-sheet.tsx
|
||||
msgid "CPU Cores"
|
||||
@@ -565,7 +565,7 @@ msgstr "Boşalıyor"
|
||||
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Disk"
|
||||
msgstr "Disk"
|
||||
msgstr "Depolama alanı"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
msgid "Disk I/O"
|
||||
@@ -836,7 +836,7 @@ msgstr "Sağlık"
|
||||
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Heartbeat"
|
||||
msgstr "Heartbeat"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Heartbeat Monitoring"
|
||||
@@ -937,7 +937,6 @@ msgstr "Yük Ort."
|
||||
msgid "Load state"
|
||||
msgstr "Yükleme durumu"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "Yükleniyor..."
|
||||
@@ -1011,7 +1010,7 @@ msgstr "Docker konteynerlerinin bellek kullanımı"
|
||||
|
||||
#: src/components/routes/system/smart-table.tsx
|
||||
msgid "Model"
|
||||
msgstr "Model"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/add-system.tsx
|
||||
#: src/components/alerts-history-columns.tsx
|
||||
@@ -1531,7 +1530,7 @@ msgstr "<0>URL</0>'yi Test Et"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Test heartbeat"
|
||||
msgstr "Test heartbeat"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/notifications.tsx
|
||||
msgid "Test notification sent"
|
||||
@@ -1582,7 +1581,7 @@ msgstr "Temayı değiştir"
|
||||
#: src/components/add-system.tsx
|
||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||
msgid "Token"
|
||||
msgstr "Token"
|
||||
msgstr "Erişim Anahtarı"
|
||||
|
||||
#: src/components/command-palette.tsx
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
@@ -1835,3 +1834,4 @@ msgstr "Evet"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "Kullanıcı ayarlarınız güncellendi."
|
||||
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Відвантажити"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Час роботи"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -1729,7 +1729,7 @@ msgstr "Tải lên"
|
||||
#: src/components/routes/system/info-bar.tsx
|
||||
#: src/components/systems-table/systems-table-columns.tsx
|
||||
msgid "Uptime"
|
||||
msgstr "Thời gian hoạt động"
|
||||
msgstr "Uptime"
|
||||
|
||||
#: src/components/routes/system.tsx
|
||||
#: src/components/routes/system.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: zh\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-31 21:16\n"
|
||||
"PO-Revision-Date: 2026-03-01 17:14\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -836,7 +836,7 @@ msgstr "健康"
|
||||
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Heartbeat"
|
||||
msgstr "Heartbeat"
|
||||
msgstr "心跳"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Heartbeat Monitoring"
|
||||
@@ -937,7 +937,6 @@ msgstr "负载"
|
||||
msgid "Load state"
|
||||
msgstr "加载状态"
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
#: src/components/systemd-table/systemd-table.tsx
|
||||
msgid "Loading..."
|
||||
msgstr "加载中..."
|
||||
@@ -1835,3 +1834,4 @@ msgstr "是"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "您的用户设置已更新。"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: zh\n"
|
||||
"Project-Id-Version: beszel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-31 21:16\n"
|
||||
"PO-Revision-Date: 2026-02-20 02:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Traditional, Hong Kong\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -836,7 +836,7 @@ msgstr "健康狀態"
|
||||
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Heartbeat"
|
||||
msgstr "Heartbeat"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/routes/settings/heartbeat.tsx
|
||||
msgid "Heartbeat Monitoring"
|
||||
@@ -1835,3 +1835,4 @@ msgstr "是"
|
||||
#: src/components/routes/settings/layout.tsx
|
||||
msgid "Your user settings have been updated."
|
||||
msgstr "您的用戶設置已更新。"
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ const Layout = () => {
|
||||
<LoginPage />
|
||||
</Suspense>
|
||||
) : (
|
||||
<div style={{ "--container": `${userSettings.layoutWidth ?? 1500}px` } as React.CSSProperties}>
|
||||
<div style={{ "--container": `${userSettings.layoutWidth ?? 1580}px` } as React.CSSProperties}>
|
||||
<div className="container">
|
||||
<Navbar />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build testing
|
||||
// +build testing
|
||||
|
||||
// Package tests provides helpers for testing the application.
|
||||
package tests
|
||||
|
||||
Reference in New Issue
Block a user