mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-18 06:08:22 +03:00
Merge pull request #8 from ibs0d/codex/fix-recording-roots-metrics-ui-and-logic
Recordings Roots: use filesystem usage for graph, show filesystem type badge, and fix locales/tests
This commit is contained in:
commit
14da24e0fa
@ -128,15 +128,15 @@
|
||||
"storage": {
|
||||
"title": "Storage",
|
||||
"overview": "Overview",
|
||||
"recordings": {
|
||||
"title": "Recordings",
|
||||
"tips": "This value represents the total storage used by the recordings in Frigate's database. Frigate does not track storage usage for all files on your disk.",
|
||||
"earliestRecording": "Earliest recording available:",
|
||||
"roots": "Recording Roots",
|
||||
"nonDefault": "Non-default root",
|
||||
"rootSummary": "Disk used: {{used}} MiB • Free: {{free}} MiB • Usage: {{usage_percent}}%",
|
||||
"rootCameras": "Cameras: {{cameras}}"
|
||||
},
|
||||
"recordings": {
|
||||
"title": "Recordings",
|
||||
"tips": "This value represents the total storage used by the recordings in Frigate's database. Frigate does not track storage usage for all files on your disk.",
|
||||
"earliestRecording": "Earliest recording available:",
|
||||
"roots": "Recording Roots",
|
||||
"rootSummary": "Disk used: {{used}} MiB \u2022 Free: {{free}} MiB \u2022 Usage: {{usage_percent}}%",
|
||||
"rootCameras": "Cameras: {{cameras}}",
|
||||
"recordingsTracked": "Frigate recordings tracked: {{recordings_size}} MiB"
|
||||
},
|
||||
"shm": {
|
||||
"title": "SHM (shared memory) allocation",
|
||||
"warning": "The current SHM size of {{total}}MB is too small. Increase it to at least {{min_shm}}MB."
|
||||
|
||||
@ -20,6 +20,7 @@ export type RecordingRootStorage = {
|
||||
cameras: string[];
|
||||
camera_usages: RootCameraStorage;
|
||||
is_default: boolean;
|
||||
filesystem?: string;
|
||||
};
|
||||
|
||||
export function RecordingsRoots({ roots }: { roots: RecordingRootStorage[] }) {
|
||||
@ -36,15 +37,15 @@ export function RecordingsRoots({ roots }: { roots: RecordingRootStorage[] }) {
|
||||
>
|
||||
<div className="mb-2 flex items-center justify-between gap-2">
|
||||
<div className="break-all text-sm font-medium">{root.path}</div>
|
||||
{!root.is_default && (
|
||||
{root.filesystem && (
|
||||
<div className="rounded-md bg-primary/15 px-2 py-1 text-xs text-primary">
|
||||
{t("storage.recordings.nonDefault")}
|
||||
{root.filesystem}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<StorageGraph
|
||||
graphId={`recordings-root-${root.path}`}
|
||||
used={root.recordings_size}
|
||||
used={root.used}
|
||||
total={root.total}
|
||||
/>
|
||||
<div className="mt-2 text-xs text-primary-variant">
|
||||
@ -54,6 +55,11 @@ export function RecordingsRoots({ roots }: { roots: RecordingRootStorage[] }) {
|
||||
usage_percent: root.usage_percent.toFixed(2),
|
||||
})}
|
||||
</div>
|
||||
<div className="mt-2 text-xs text-primary-variant">
|
||||
{t("storage.recordings.recordingsTracked", {
|
||||
recordings_size: root.recordings_size,
|
||||
})}
|
||||
</div>
|
||||
<div className="mt-2 text-xs text-muted-foreground">
|
||||
{t("storage.recordings.rootCameras", {
|
||||
cameras:
|
||||
|
||||
@ -5,11 +5,13 @@ import { RecordingsRoots, type RecordingRootStorage } from "../RecordingsRoots";
|
||||
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string, opts?: Record<string, string>) => {
|
||||
if (key === "storage.recordings.nonDefault") return "Non-default root";
|
||||
t: (key: string, opts?: Record<string, string | number>) => {
|
||||
if (key === "storage.recordings.rootSummary") {
|
||||
return `Disk used: ${opts?.used} MiB • Free: ${opts?.free} MiB • Usage: ${opts?.usage_percent}%`;
|
||||
}
|
||||
if (key === "storage.recordings.recordingsTracked") {
|
||||
return `Frigate recordings tracked: ${opts?.recordings_size} MiB`;
|
||||
}
|
||||
if (key === "storage.recordings.rootCameras") {
|
||||
return `Cameras: ${opts?.cameras}`;
|
||||
}
|
||||
@ -20,7 +22,7 @@ vi.mock("react-i18next", () => ({
|
||||
}));
|
||||
|
||||
describe("RecordingsRoots", () => {
|
||||
it("renders multiple roots and per-camera usage", () => {
|
||||
it("renders multiple roots, filesystem details, and per-camera usage", () => {
|
||||
const roots: RecordingRootStorage[] = [
|
||||
{
|
||||
path: "/media/frigate/recordings",
|
||||
@ -31,6 +33,7 @@ describe("RecordingsRoots", () => {
|
||||
recordings_size: 600,
|
||||
cameras: ["front_door"],
|
||||
is_default: true,
|
||||
filesystem: "ext4 • /media/frigate",
|
||||
camera_usages: {
|
||||
front_door: { bandwidth: 5, usage: 600, usage_percent: 100 },
|
||||
},
|
||||
@ -44,6 +47,7 @@ describe("RecordingsRoots", () => {
|
||||
recordings_size: 800,
|
||||
cameras: ["back_yard", "garage"],
|
||||
is_default: false,
|
||||
filesystem: "xfs • /mnt",
|
||||
camera_usages: {
|
||||
back_yard: { bandwidth: 4, usage: 300, usage_percent: 37.5 },
|
||||
garage: { bandwidth: 6, usage: 500, usage_percent: 62.5 },
|
||||
@ -55,7 +59,11 @@ describe("RecordingsRoots", () => {
|
||||
|
||||
expect(html).toContain("/media/frigate/recordings");
|
||||
expect(html).toContain("/mnt/custom-recordings");
|
||||
expect(html).toContain("Non-default root");
|
||||
expect(html).toContain("ext4 • /media/frigate");
|
||||
expect(html).toContain("xfs • /mnt");
|
||||
expect(html).not.toContain("Non-default root");
|
||||
expect(html).toContain("Disk used: 700 MiB • Free: 300 MiB • Usage: 70.00%");
|
||||
expect(html).toContain("Frigate recordings tracked: 600 MiB");
|
||||
expect(html).toContain("Cameras: back yard, garage");
|
||||
expect(html).toContain("garage");
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user