mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-30 03:00:41 -04:00
feat(frontend): show workspace storage usage in usage limits panel
Add file storage bar to the CoPilot usage limits popover showing used/limit bytes, percentage, and file count. Fetches from the existing GET /workspace/storage/usage endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { Button } from "@/components/atoms/Button/Button";
|
||||
import Link from "next/link";
|
||||
import { formatCents } from "../RateLimitResetDialog/RateLimitResetDialog";
|
||||
import { useResetRateLimit } from "../../hooks/useResetRateLimit";
|
||||
import { useWorkspaceStorage } from "./useWorkspaceStorage";
|
||||
|
||||
export function formatResetTime(
|
||||
resetsAt: Date | string,
|
||||
@@ -73,6 +74,57 @@ function UsageBar({
|
||||
);
|
||||
}
|
||||
|
||||
export function formatBytes(bytes: number): string {
|
||||
if (bytes < 1024) return `${bytes} B`;
|
||||
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
|
||||
if (bytes < 1024 * 1024 * 1024)
|
||||
return `${(bytes / (1024 * 1024)).toFixed(0)} MB`;
|
||||
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
||||
}
|
||||
|
||||
function StorageBar({
|
||||
usedBytes,
|
||||
limitBytes,
|
||||
fileCount,
|
||||
}: {
|
||||
usedBytes: number;
|
||||
limitBytes: number;
|
||||
fileCount: number;
|
||||
}) {
|
||||
if (limitBytes <= 0) return null;
|
||||
|
||||
const rawPercent = (usedBytes / limitBytes) * 100;
|
||||
const percent = Math.min(100, Math.round(rawPercent));
|
||||
const isHigh = percent >= 80;
|
||||
const percentLabel =
|
||||
usedBytes > 0 && percent === 0 ? "<1% used" : `${percent}% used`;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-baseline justify-between">
|
||||
<span className="text-xs font-medium text-neutral-700">
|
||||
File storage
|
||||
</span>
|
||||
<span className="text-[11px] tabular-nums text-neutral-500">
|
||||
{percentLabel}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-[10px] text-neutral-400">
|
||||
{formatBytes(usedBytes)} of {formatBytes(limitBytes)} ·{" "}
|
||||
{fileCount} {fileCount === 1 ? "file" : "files"}
|
||||
</div>
|
||||
<div className="h-2 w-full overflow-hidden rounded-full bg-neutral-200">
|
||||
<div
|
||||
className={`h-full rounded-full transition-[width] duration-300 ease-out ${
|
||||
isHigh ? "bg-orange-500" : "bg-blue-500"
|
||||
}`}
|
||||
style={{ width: `${Math.max(usedBytes > 0 ? 1 : 0, percent)}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ResetButton({
|
||||
cost,
|
||||
onCreditChange,
|
||||
@@ -97,6 +149,19 @@ function ResetButton({
|
||||
);
|
||||
}
|
||||
|
||||
function WorkspaceStorageSection() {
|
||||
const { data: storage } = useWorkspaceStorage();
|
||||
if (!storage || storage.limit_bytes <= 0) return null;
|
||||
|
||||
return (
|
||||
<StorageBar
|
||||
usedBytes={storage.used_bytes}
|
||||
limitBytes={storage.limit_bytes}
|
||||
fileCount={storage.file_count}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function UsagePanelContent({
|
||||
usage,
|
||||
showBillingLink = true,
|
||||
@@ -154,6 +219,7 @@ export function UsagePanelContent({
|
||||
resetsAt={usage.weekly.resets_at}
|
||||
/>
|
||||
)}
|
||||
<WorkspaceStorageSection />
|
||||
{isDailyExhausted &&
|
||||
!isWeeklyExhausted &&
|
||||
resetCost > 0 &&
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { customMutator } from "@/app/api/mutators/custom-mutator";
|
||||
|
||||
type StorageUsage = {
|
||||
used_bytes: number;
|
||||
limit_bytes: number;
|
||||
used_percent: number;
|
||||
file_count: number;
|
||||
};
|
||||
|
||||
export function useWorkspaceStorage() {
|
||||
return useQuery({
|
||||
queryKey: ["workspace", "storage", "usage"],
|
||||
queryFn: async () => {
|
||||
const res = await customMutator<{
|
||||
data: StorageUsage;
|
||||
status: number;
|
||||
headers: Headers;
|
||||
}>("/api/workspace/storage/usage", { method: "GET" });
|
||||
return res.data;
|
||||
},
|
||||
staleTime: 30000,
|
||||
refetchInterval: 60000,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user