@burdenoff/microfe-files 2026.530.1 → 2026.530.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/files/components/StorageBanner.js +64 -0
- package/dist/files/components/StorageBanner.js.map +1 -0
- package/dist/files/hooks/useStorageQuota.js +37 -0
- package/dist/files/hooks/useStorageQuota.js.map +1 -0
- package/dist/files/pages/BrowserPage.js +230 -224
- package/dist/files/pages/BrowserPage.js.map +1 -1
- package/dist/generated/wspace-operations.js +33 -15
- package/dist/generated/wspace-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AlertCircle as e, AlertTriangle as t } from "lucide-react";
|
|
2
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
3
|
+
//#region src/files/components/StorageBanner.tsx
|
|
4
|
+
function i(e) {
|
|
5
|
+
return e >= 1073741824 ? `${(e / 1073741824).toFixed(1)} GB` : e >= 1048576 ? `${(e / 1048576).toFixed(1)} MB` : e >= 1024 ? `${(e / 1024).toFixed(1)} KB` : `${e} B`;
|
|
6
|
+
}
|
|
7
|
+
var a = ({ quota: a }) => {
|
|
8
|
+
if (a.loading || a.noLimit || !a.isExhausted && !a.isNearLimit) return null;
|
|
9
|
+
let o = i(a.usedBytes), s = a.limitBytes ? i(a.limitBytes) : null;
|
|
10
|
+
return a.isExhausted ? /* @__PURE__ */ r("div", {
|
|
11
|
+
className: "flex items-center gap-3 rounded-lg border border-status-error-bg/30 bg-status-error-bg/10 px-4 py-3 text-sm",
|
|
12
|
+
children: [
|
|
13
|
+
/* @__PURE__ */ n(e, { className: "size-4 shrink-0 text-status-error-bg" }),
|
|
14
|
+
/* @__PURE__ */ r("div", {
|
|
15
|
+
className: "flex flex-1 items-center gap-1 text-text-primary",
|
|
16
|
+
children: [/* @__PURE__ */ n("span", {
|
|
17
|
+
className: "font-medium",
|
|
18
|
+
children: "Storage full."
|
|
19
|
+
}), /* @__PURE__ */ r("span", {
|
|
20
|
+
className: "text-text-secondary",
|
|
21
|
+
children: [
|
|
22
|
+
s ? `${o} of ${s} used — no space left.` : `${o} used — no space left.`,
|
|
23
|
+
" ",
|
|
24
|
+
"Delete files to free up space or upgrade your plan."
|
|
25
|
+
]
|
|
26
|
+
})]
|
|
27
|
+
}),
|
|
28
|
+
/* @__PURE__ */ n("div", {
|
|
29
|
+
className: "h-1.5 w-24 shrink-0 overflow-hidden rounded-full bg-surface-tertiary",
|
|
30
|
+
children: /* @__PURE__ */ n("div", { className: "h-full w-full rounded-full bg-status-error-bg" })
|
|
31
|
+
})
|
|
32
|
+
]
|
|
33
|
+
}) : /* @__PURE__ */ r("div", {
|
|
34
|
+
className: "flex items-center gap-3 rounded-lg border border-status-warning-bg/30 bg-status-warning-bg/10 px-4 py-3 text-sm",
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ n(t, { className: "size-4 shrink-0 text-status-warning-bg" }),
|
|
37
|
+
/* @__PURE__ */ r("div", {
|
|
38
|
+
className: "flex flex-1 items-center gap-1 text-text-primary",
|
|
39
|
+
children: [/* @__PURE__ */ n("span", {
|
|
40
|
+
className: "font-medium",
|
|
41
|
+
children: "Storage almost full."
|
|
42
|
+
}), /* @__PURE__ */ r("span", {
|
|
43
|
+
className: "text-text-secondary",
|
|
44
|
+
children: [
|
|
45
|
+
s ? `${o} of ${s} used (${Math.round(a.usedPercent)}%).` : `${o} used.`,
|
|
46
|
+
" ",
|
|
47
|
+
"Consider deleting files or upgrading your plan."
|
|
48
|
+
]
|
|
49
|
+
})]
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ n("div", {
|
|
52
|
+
className: "h-1.5 w-24 shrink-0 overflow-hidden rounded-full bg-surface-tertiary",
|
|
53
|
+
children: /* @__PURE__ */ n("div", {
|
|
54
|
+
className: "h-full rounded-full bg-status-warning-bg transition-all",
|
|
55
|
+
style: { width: `${a.usedPercent}%` }
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
export { a as StorageBanner };
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=StorageBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StorageBanner.js","names":[],"sources":["../../../src/files/components/StorageBanner.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { AlertCircle, AlertTriangle, HardDrive } from \"lucide-react\";\nimport type { StorageQuotaState } from \"../hooks/useStorageQuota\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes >= 1073741824) return `${(bytes / 1073741824).toFixed(1)} GB`;\n if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`;\n if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${bytes} B`;\n}\n\ninterface StorageBannerProps {\n quota: StorageQuotaState;\n}\n\nexport const StorageBanner: FC<StorageBannerProps> = ({ quota }) => {\n if (\n quota.loading ||\n quota.noLimit ||\n (!quota.isExhausted && !quota.isNearLimit)\n ) {\n return null;\n }\n\n const usedLabel = formatBytes(quota.usedBytes);\n const limitLabel = quota.limitBytes ? formatBytes(quota.limitBytes) : null;\n\n if (quota.isExhausted) {\n return (\n <div className=\"flex items-center gap-3 rounded-lg border border-status-error-bg/30 bg-status-error-bg/10 px-4 py-3 text-sm\">\n <AlertCircle className=\"size-4 shrink-0 text-status-error-bg\" />\n <div className=\"flex flex-1 items-center gap-1 text-text-primary\">\n <span className=\"font-medium\">Storage full.</span>\n <span className=\"text-text-secondary\">\n {limitLabel\n ? `${usedLabel} of ${limitLabel} used — no space left.`\n : `${usedLabel} used — no space left.`}{\" \"}\n Delete files to free up space or upgrade your plan.\n </span>\n </div>\n <div className=\"h-1.5 w-24 shrink-0 overflow-hidden rounded-full bg-surface-tertiary\">\n <div className=\"h-full w-full rounded-full bg-status-error-bg\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center gap-3 rounded-lg border border-status-warning-bg/30 bg-status-warning-bg/10 px-4 py-3 text-sm\">\n <AlertTriangle className=\"size-4 shrink-0 text-status-warning-bg\" />\n <div className=\"flex flex-1 items-center gap-1 text-text-primary\">\n <span className=\"font-medium\">Storage almost full.</span>\n <span className=\"text-text-secondary\">\n {limitLabel\n ? `${usedLabel} of ${limitLabel} used (${Math.round(quota.usedPercent)}%).`\n : `${usedLabel} used.`}{\" \"}\n Consider deleting files or upgrading your plan.\n </span>\n </div>\n <div className=\"h-1.5 w-24 shrink-0 overflow-hidden rounded-full bg-surface-tertiary\">\n <div\n className=\"h-full rounded-full bg-status-warning-bg transition-all\"\n style={{ width: `${quota.usedPercent}%` }}\n />\n </div>\n </div>\n );\n};\n\ninterface StorageIndicatorProps {\n quota: StorageQuotaState;\n}\n\nexport const StorageIndicator: FC<StorageIndicatorProps> = ({ quota }) => {\n if (quota.loading || quota.noLimit || !quota.limitBytes) return null;\n\n const usedLabel = formatBytes(quota.usedBytes);\n const limitLabel = formatBytes(quota.limitBytes);\n const color = quota.isExhausted\n ? \"bg-status-error-bg\"\n : quota.isNearLimit\n ? \"bg-status-warning-bg\"\n : \"bg-status-info-bg\";\n\n return (\n <div className=\"flex items-center gap-2 text-xs text-text-muted\">\n <HardDrive className=\"size-3.5 shrink-0\" />\n <span>\n {usedLabel} / {limitLabel}\n </span>\n <div className=\"h-1 w-16 overflow-hidden rounded-full bg-surface-tertiary\">\n <div\n className={`h-full rounded-full transition-all ${color}`}\n style={{ width: `${quota.usedPercent}%` }}\n />\n </div>\n </div>\n );\n};\n"],"mappings":";;;AAIA,SAAS,EAAY,GAAuB;AAI1C,QAHI,KAAS,aAAmB,IAAI,IAAQ,YAAY,QAAQ,EAAE,CAAC,OAC/D,KAAS,UAAgB,IAAI,IAAQ,SAAS,QAAQ,EAAE,CAAC,OACzD,KAAS,OAAa,IAAI,IAAQ,MAAM,QAAQ,EAAE,CAAC,OAChD,GAAG,EAAM;;AAOlB,IAAa,KAAyC,EAAE,eAAY;AAClE,KACE,EAAM,WACN,EAAM,WACL,CAAC,EAAM,eAAe,CAAC,EAAM,YAE9B,QAAO;CAGT,IAAM,IAAY,EAAY,EAAM,UAAU,EACxC,IAAa,EAAM,aAAa,EAAY,EAAM,WAAW,GAAG;AAsBtE,QApBI,EAAM,cAEN,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAa,WAAU,wCAAyC,CAAA;GAChE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAAc;KAAoB,CAAA,EAClD,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACG,IACG,GAAG,EAAU,MAAM,EAAW,0BAC9B,GAAG,EAAU;MAAyB;MAAI;MAEzC;OACH;;GACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD,EAAK,WAAU,iDAAkD,CAAA;IAC7D,CAAA;GACF;MAKR,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAe,WAAU,0CAA2C,CAAA;GACpE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAAc;KAA2B,CAAA,EACzD,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACG,IACG,GAAG,EAAU,MAAM,EAAW,SAAS,KAAK,MAAM,EAAM,YAAY,CAAC,OACrE,GAAG,EAAU;MAAS;MAAI;MAEzB;OACH;;GACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KACE,WAAU;KACV,OAAO,EAAE,OAAO,GAAG,EAAM,YAAY,IAAI;KACzC,CAAA;IACE,CAAA;GACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useGetWorkspaceStorageStatusQuery as e } from "../../generated/wspace-operations.js";
|
|
2
|
+
import { useMemo as t } from "react";
|
|
3
|
+
//#region src/files/hooks/useStorageQuota.ts
|
|
4
|
+
var n = "vibecontrols.files.storage_bytes";
|
|
5
|
+
function r(r) {
|
|
6
|
+
let { data: i, loading: a } = e({
|
|
7
|
+
variables: { workspaceId: r },
|
|
8
|
+
skip: !r,
|
|
9
|
+
pollInterval: 6e4
|
|
10
|
+
});
|
|
11
|
+
return t(() => {
|
|
12
|
+
let e = i?.workspaceQuotaStatuses.find((e) => e.quotaName === n);
|
|
13
|
+
if (!e) return {
|
|
14
|
+
usedBytes: 0,
|
|
15
|
+
limitBytes: null,
|
|
16
|
+
noLimit: !0,
|
|
17
|
+
usedPercent: 0,
|
|
18
|
+
isExhausted: !1,
|
|
19
|
+
isNearLimit: !1,
|
|
20
|
+
loading: a
|
|
21
|
+
};
|
|
22
|
+
let t = e.currentValue, r = e.noLimit ? null : e.limit ?? null, o = r && r > 0 ? Math.min(100, t / r * 100) : 0;
|
|
23
|
+
return {
|
|
24
|
+
usedBytes: t,
|
|
25
|
+
limitBytes: r,
|
|
26
|
+
noLimit: e.noLimit,
|
|
27
|
+
usedPercent: o,
|
|
28
|
+
isExhausted: !e.noLimit && t >= (r ?? Infinity),
|
|
29
|
+
isNearLimit: !e.noLimit && o >= 80,
|
|
30
|
+
loading: a
|
|
31
|
+
};
|
|
32
|
+
}, [i, a]);
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { r as useStorageQuota };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=useStorageQuota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStorageQuota.js","names":[],"sources":["../../../src/files/hooks/useStorageQuota.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useGetWorkspaceStorageStatusQuery } from \"../../generated/wspace-operations\";\n\nconst STORAGE_QUOTA_NAME = \"vibecontrols.files.storage_bytes\";\n\nexport interface StorageQuotaState {\n usedBytes: number;\n limitBytes: number | null;\n noLimit: boolean;\n usedPercent: number;\n isExhausted: boolean;\n isNearLimit: boolean;\n loading: boolean;\n}\n\nexport function useStorageQuota(workspaceId: string): StorageQuotaState {\n const { data, loading } = useGetWorkspaceStorageStatusQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n pollInterval: 60_000,\n });\n\n return useMemo(() => {\n const status = data?.workspaceQuotaStatuses.find(\n (s: { quotaName: string }) => s.quotaName === STORAGE_QUOTA_NAME,\n );\n\n if (!status) {\n return {\n usedBytes: 0,\n limitBytes: null,\n noLimit: true,\n usedPercent: 0,\n isExhausted: false,\n isNearLimit: false,\n loading,\n };\n }\n\n const usedBytes = status.currentValue;\n const limitBytes = status.noLimit ? null : (status.limit ?? null);\n const usedPercent =\n limitBytes && limitBytes > 0\n ? Math.min(100, (usedBytes / limitBytes) * 100)\n : 0;\n\n return {\n usedBytes,\n limitBytes,\n noLimit: status.noLimit,\n usedPercent,\n isExhausted: !status.noLimit && usedBytes >= (limitBytes ?? Infinity),\n isNearLimit: !status.noLimit && usedPercent >= 80,\n loading,\n };\n }, [data, loading]);\n}\n"],"mappings":";;;AAGA,IAAM,IAAqB;AAY3B,SAAgB,EAAgB,GAAwC;CACtE,IAAM,EAAE,SAAM,eAAY,EAAkC;EAC1D,WAAW,EAAE,gBAAa;EAC1B,MAAM,CAAC;EACP,cAAc;EACf,CAAC;AAEF,QAAO,QAAc;EACnB,IAAM,IAAS,GAAM,uBAAuB,MACzC,MAA6B,EAAE,cAAc,EAC/C;AAED,MAAI,CAAC,EACH,QAAO;GACL,WAAW;GACX,YAAY;GACZ,SAAS;GACT,aAAa;GACb,aAAa;GACb,aAAa;GACb;GACD;EAGH,IAAM,IAAY,EAAO,cACnB,IAAa,EAAO,UAAU,OAAQ,EAAO,SAAS,MACtD,IACJ,KAAc,IAAa,IACvB,KAAK,IAAI,KAAM,IAAY,IAAc,IAAI,GAC7C;AAEN,SAAO;GACL;GACA;GACA,SAAS,EAAO;GAChB;GACA,aAAa,CAAC,EAAO,WAAW,MAAc,KAAc;GAC5D,aAAa,CAAC,EAAO,WAAW,KAAe;GAC/C;GACD;IACA,CAAC,GAAM,EAAQ,CAAC"}
|