mirror of
https://github.com/henrygd/beszel.git
synced 2025-12-16 18:26:16 +01:00
add secondsToString function
This commit is contained in:
@@ -45,6 +45,7 @@ import {
|
||||
debounce,
|
||||
decimalString,
|
||||
formatBytes,
|
||||
secondsToString,
|
||||
getHostDisplayValue,
|
||||
listen,
|
||||
parseSemVer,
|
||||
@@ -358,21 +359,13 @@ export default memo(function SystemDetail({ id }: { id: string }) {
|
||||
value: system.info.k,
|
||||
},
|
||||
}
|
||||
let uptime: React.ReactNode
|
||||
let uptime: string
|
||||
if (system.info.u < 3600) {
|
||||
uptime = (
|
||||
<Plural
|
||||
value={Math.trunc(system.info.u / 60)}
|
||||
one="# minute"
|
||||
few="# minutes"
|
||||
many="# minutes"
|
||||
other="# minutes"
|
||||
/>
|
||||
)
|
||||
} else if (system.info.u < 172800) {
|
||||
uptime = <Plural value={Math.trunc(system.info.u / 3600)} one="# hour" other="# hours" />
|
||||
uptime = secondsToString(system.info.u, "minute")
|
||||
} else if (system.info.u * 360000) {
|
||||
uptime = secondsToString(system.info.u, "hour")
|
||||
} else {
|
||||
uptime = <Plural value={Math.trunc(system.info?.u / 86400)} one="# day" other="# days" />
|
||||
uptime = secondsToString(system.info.u, "day")
|
||||
}
|
||||
return [
|
||||
{ value: getHostDisplayValue(system), Icon: GlobeIcon },
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
SortingState,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table"
|
||||
import { Activity, Box, Clock, HardDrive, HashIcon, CpuIcon, BinaryIcon, RotateCwIcon, LoaderCircleIcon, CheckCircle2Icon, XCircleIcon, ArrowLeftRightIcon, ArrowUpDownIcon } from "lucide-react"
|
||||
import { Activity, Box, Clock, HardDrive, HashIcon, CpuIcon, BinaryIcon, RotateCwIcon, LoaderCircleIcon, CheckCircle2Icon, XCircleIcon, ArrowLeftRightIcon } from "lucide-react"
|
||||
import { Card, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
|
||||
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "@/components/ui/sheet"
|
||||
import { Input } from "@/components/ui/input"
|
||||
@@ -27,7 +27,7 @@ import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { pb } from "@/lib/api"
|
||||
import { SmartData, SmartAttribute } from "@/types"
|
||||
import { formatBytes, toFixedFloat, formatTemperature, cn } from "@/lib/utils"
|
||||
import { formatBytes, toFixedFloat, formatTemperature, cn, secondsToString } from "@/lib/utils"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { ThermometerIcon } from "@/components/ui/icons"
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||||
@@ -172,8 +172,8 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
||||
accessorKey: "powerOnHours",
|
||||
invertSorting: true,
|
||||
header: ({ column }) => <HeaderButton column={column} name={t({ message: "Power On", comment: "Power On Time" })} Icon={Clock} />,
|
||||
cell: ({ row }) => {
|
||||
const hours = row.getValue("powerOnHours") as number | undefined
|
||||
cell: ({ getValue }) => {
|
||||
const hours = (getValue() ?? 0) as number
|
||||
if (!hours && hours !== 0) {
|
||||
return (
|
||||
<div className="text-sm text-muted-foreground ms-1.5">
|
||||
@@ -181,11 +181,11 @@ export const columns: ColumnDef<DiskInfo>[] = [
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const days = Math.floor(hours / 24)
|
||||
const seconds = hours * 3600
|
||||
return (
|
||||
<div className="text-sm ms-1.5">
|
||||
<div>{hours.toLocaleString()} hours</div>
|
||||
<div className="text-muted-foreground text-xs">{days} days</div>
|
||||
<div>{secondsToString(seconds, "hour")}</div>
|
||||
<div className="text-muted-foreground text-xs">{secondsToString(seconds, "day")}</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
@@ -234,7 +234,6 @@ function HeaderButton({ column, name, Icon }: { column: Column<DiskInfo>; name:
|
||||
>
|
||||
{Icon && <Icon className="size-4" />}
|
||||
{name}
|
||||
<ArrowUpDownIcon className="size-4" />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -342,7 +341,7 @@ export default function DisksTable({ systemId }: { systemId: string }) {
|
||||
onClick={() => openSheet(row.original)}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
<TableCell key={cell.id} className="md:ps-5">
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { t } from "@lingui/core/macro"
|
||||
import { plural, t } from "@lingui/core/macro"
|
||||
import { type ClassValue, clsx } from "clsx"
|
||||
import { listenKeys } from "nanostores"
|
||||
import { timeDay, timeHour, timeMinute } from "d3-time"
|
||||
@@ -111,18 +111,17 @@ export const updateFavicon = (() => {
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill="url(#gradient)" d="M35 70H0V0h35q4.4 0 8.2 1.7a21.4 21.4 0 0 1 6.6 4.5q2.9 2.8 4.5 6.6Q56 16.7 56 21a15.4 15.4 0 0 1-.3 3.2 17.6 17.6 0 0 1-.2.8 19.4 19.4 0 0 1-1.5 4 17 17 0 0 1-2.4 3.4 13.5 13.5 0 0 1-2.6 2.3 12.5 12.5 0 0 1-.4.3q1.7 1 3 2.5Q53 39.1 54 41a18.3 18.3 0 0 1 1.5 4 17.4 17.4 0 0 1 .5 3 15.3 15.3 0 0 1 0 1q0 4.4-1.7 8.2a21.4 21.4 0 0 1-4.5 6.6q-2.8 2.9-6.6 4.6Q39.4 70 35 70ZM14 14v14h21a7 7 0 0 0 2.3-.3 6.6 6.6 0 0 0 .4-.2Q39 27 40 26a6.9 6.9 0 0 0 1.5-2.2q.5-1.3.5-2.8a7 7 0 0 0-.4-2.3 6.6 6.6 0 0 0-.1-.4Q40.9 17 40 16a7 7 0 0 0-2.3-1.4 6.9 6.9 0 0 0-2.5-.6 7.9 7.9 0 0 0-.2 0H14Zm0 28v14h21a7 7 0 0 0 2.3-.4 6.6 6.6 0 0 0 .4-.1Q39 54.9 40 54a7 7 0 0 0 1.5-2.2 6.9 6.9 0 0 0 .5-2.6 7.9 7.9 0 0 0 0-.2 7 7 0 0 0-.4-2.3 6.6 6.6 0 0 0-.1-.4Q40.9 45 40 44a7 7 0 0 0-2.3-1.5 6.9 6.9 0 0 0-2.5-.6 7.9 7.9 0 0 0-.2 0H14Z"/>
|
||||
${
|
||||
downCount > 0 &&
|
||||
`
|
||||
${downCount > 0 &&
|
||||
`
|
||||
<circle cx="40" cy="50" r="22" fill="#f00"/>
|
||||
<text x="40" y="60" font-size="34" text-anchor="middle" fill="#fff" font-family="Arial" font-weight="bold">${downCount}</text>
|
||||
`
|
||||
}
|
||||
}
|
||||
</svg>
|
||||
`
|
||||
const blob = new Blob([svg], { type: "image/svg+xml" })
|
||||
const url = URL.createObjectURL(blob)
|
||||
;(document.querySelector("link[rel='icon']") as HTMLLinkElement).href = url
|
||||
; (document.querySelector("link[rel='icon']") as HTMLLinkElement).href = url
|
||||
}
|
||||
})()
|
||||
|
||||
@@ -429,3 +428,17 @@ export function runOnce<T extends (...args: any[]) => any>(fn: T): T {
|
||||
return state.result
|
||||
}) as T
|
||||
}
|
||||
|
||||
/** Format seconds to hours, minutes, or seconds */
|
||||
export function secondsToString(seconds: number, unit: "hour" | "minute" | "day"): string {
|
||||
const count = Math.floor(seconds / (unit === "hour" ? 3600 : unit === "minute" ? 60 : 86400))
|
||||
const countString = count.toLocaleString()
|
||||
switch (unit) {
|
||||
case "minute":
|
||||
return plural(count, { one: `${countString} minute`, few: `${countString} minutes`, many: `${countString} minutes`, other: `${countString} minutes` })
|
||||
case "hour":
|
||||
return plural(count, { one: `${countString} hour`, other: `${countString} hours` })
|
||||
case "day":
|
||||
return plural(count, { one: `${countString} day`, other: `${countString} days` })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user