Add quota changes to frontend usage bar

This commit is contained in:
Jon_K 2026-01-03 02:27:20 -05:00
parent 5c479c9b58
commit 58e48a449e
2 changed files with 59 additions and 2 deletions

View File

@ -90,9 +90,9 @@
v-if="isFiles && !disableUsedPercentage"
style="width: 90%; margin: 2em 2.5em 3em 2.5em"
>
<progress-bar :val="usage.usedPercentage" size="small"></progress-bar>
<progress-bar :val="usagePercentage" size="small"></progress-bar>
<br />
{{ usage.used }} of {{ usage.total }} used
{{ usedFormatted }} of {{ totalFormatted }} used
</div>
<p class="credits">
@ -161,6 +161,37 @@ export default {
disableExternal: () => disableExternal,
disableUsedPercentage: () => disableUsedPercentage,
canLogout: () => !noAuth && (loginPage || logoutPage !== "/login"),
hasQuotaData() {
return this.user?.quotaLimit && this.user.quotaLimit > 0;
},
quotaLimitBytes() {
// QuotaLimit is already stored in bytes in the backend
return this.user?.quotaLimit || 0;
},
quotaUsedBytes() {
// QuotaUsed is already in bytes
return this.user?.quotaUsed || 0;
},
// Unified properties that use quota if available, otherwise disk usage
usagePercentage() {
if (this.hasQuotaData) {
if (this.quotaLimitBytes === 0) return 0;
return Math.min(Math.round((this.quotaUsedBytes / this.quotaLimitBytes) * 100), 100);
}
return this.usage.usedPercentage;
},
usedFormatted() {
if (this.hasQuotaData) {
return prettyBytes(this.quotaUsedBytes, { binary: true });
}
return this.usage.used;
},
totalFormatted() {
if (this.hasQuotaData) {
return prettyBytes(this.quotaLimitBytes, { binary: true });
}
return this.usage.total;
},
},
methods: {
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
@ -168,6 +199,11 @@ export default {
this.usageAbortController.abort();
},
async fetchUsage() {
// If user has quota, don't fetch disk usage
if (this.hasQuotaData) {
return;
}
const path = this.$route.path.endsWith("/")
? this.$route.path
: this.$route.path + "/";

View File

@ -34,6 +34,10 @@ type userInfo struct {
DateFormat bool `json:"dateFormat"`
Username string `json:"username"`
AceEditorTheme string `json:"aceEditorTheme"`
QuotaLimit uint64 `json:"quotaLimit"`
QuotaUnit string `json:"quotaUnit"`
EnforceQuota bool `json:"enforceQuota"`
QuotaUsed uint64 `json:"quotaUsed"`
}
type authToken struct {
@ -202,6 +206,19 @@ func renewHandler(tokenExpireTime time.Duration) handleFunc {
}
func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User, tokenExpirationTime time.Duration) (int, error) {
// Calculate current quota usage if quota is enabled
var quotaUsed uint64
if user.QuotaLimit > 0 {
used, err := users.CalculateUserQuota(user.Fs, user.Scope)
if err != nil {
// Log error but don't fail login - just set usage to 0
log.Printf("Failed to calculate quota for user %s: %v", user.Username, err)
quotaUsed = 0
} else {
quotaUsed = used
}
}
claims := &authToken{
User: userInfo{
ID: user.ID,
@ -215,6 +232,10 @@ func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.Use
DateFormat: user.DateFormat,
Username: user.Username,
AceEditorTheme: user.AceEditorTheme,
QuotaLimit: user.QuotaLimit,
QuotaUnit: user.QuotaUnit,
EnforceQuota: user.EnforceQuota,
QuotaUsed: quotaUsed,
},
RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()),