Show storage meter even with no quota (#1240)

- Displays how much storage items and browser profiles take up even when quota is not specified
This commit is contained in:
sua yoo 2023-10-02 20:01:39 -07:00 committed by GitHub
parent 941a75ef12
commit 3fea4cabe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 68 deletions

View File

@ -50,7 +50,7 @@ export class Meter extends LitElement {
min = 0;
@property({ type: Number })
max = 100;
max?: number;
@property({ type: Number })
value = 0;
@ -106,16 +106,16 @@ export class Meter extends LitElement {
}
.valueText {
display: inline-flex;
display: inline-block;
}
.valueText.withSeparator:after {
.maxText.withSeparator:before {
content: "/";
padding: 0 0.3ch;
}
.maxText {
display: inline-block;
display: inline-flex;
}
`;
@ -130,8 +130,9 @@ export class Meter extends LitElement {
render() {
// meter spec disallow values that exceed max
const boundedValue = Math.max(Math.min(this.value, this.max), this.min);
const barWidth = `${(boundedValue / this.max) * 100}%`;
const max = this.max ? Math.max(this.value, this.max) : this.value;
const boundedValue = Math.max(Math.min(this.value, max), this.min);
const barWidth = `${(boundedValue / max) * 100}%`;
return html`
<div
class="meter"
@ -139,27 +140,29 @@ export class Meter extends LitElement {
aria-valuenow=${boundedValue}
aria-valuetext=${ifDefined(this.valueText)}
aria-valuemin=${this.min}
aria-valuemax=${this.max}
aria-valuemax=${max}
>
<sl-resize-observer @sl-resize=${this.onTrackResize}>
<div class="track">
<div class="valueBar" style="width:${barWidth}">
<slot @slotchange=${this.handleSlotchange}></slot>
</div>
${this.value < this.max ? html`<slot name="available"></slot>` : ""}
${this.value < max ? html`<slot name="available"></slot>` : ""}
</div>
</sl-resize-observer>
<div class="labels">
<div class="label value" style="width:${barWidth}">
<span class="valueText withSeparator">
<slot name="valueLabel">${this.value}</slot>
</span>
</div>
<div class="label max">
<span class="maxText">
<slot name="maxLabel">${this.max}</slot>
<span class="valueText">
<slot name="valueLabel"></slot>
</span>
</div>
${this.max
? html`<div class="label max">
<span class="maxText withSeparator">
<slot name="maxLabel"></slot>
</span>
</div>`
: ""}
</div>
</div>
`;
@ -181,21 +184,22 @@ export class Meter extends LitElement {
const remaining = Math.ceil(trackW - barWidth - pad);
// Show compact value/max label when almost touching
const valueText = this.labels?.querySelector(".valueText");
if (this.maxText && this.maxText.clientWidth >= remaining) {
valueText?.classList.add("withSeparator");
if (this.maxText.clientWidth >= remaining) {
this.maxText.classList.add("withSeparator");
} else {
valueText?.classList.remove("withSeparator");
this.maxText.classList.remove("withSeparator");
}
}
private handleSlotchange() {
if (!this.bars) return;
this.bars.forEach((el, i, arr) => {
if (i < arr.length - 1) {
el.style.cssText +=
"--border-right: 1px solid var(--sl-color-neutral-600)";
}
});
if (this.bars.length > 1) {
this.bars.forEach((el, i, arr) => {
if (i < arr.length - 1) {
el.style.cssText +=
"--border-right: 1px solid var(--sl-color-neutral-600)";
}
});
}
}
}

View File

@ -116,27 +116,8 @@ export class Dashboard extends LiteElement {
${this.renderCard(
msg("Storage"),
(metrics) => html`
${when(metrics.storageQuotaBytes, () =>
this.renderStorageMeter(metrics)
)}
${this.renderStorageMeter(metrics)}
<dl>
${when(
!metrics.storageQuotaBytes,
() => html`
${this.renderStat({
value: html`<sl-format-bytes
value=${metrics.storageUsedBytes ?? 0}
display="narrow"
></sl-format-bytes>`,
singleLabel: msg("of Data Stored"),
pluralLabel: msg("of Data Stored"),
iconProps: { name: "device-hdd-fill" },
})}
<sl-divider
style="--spacing:var(--sl-spacing-small)"
></sl-divider>
`
)}
${this.renderStat({
value: metrics.crawlCount,
singleLabel: msg("Crawl"),
@ -226,12 +207,9 @@ export class Dashboard extends LiteElement {
}
private renderStorageMeter(metrics: Metrics) {
// Account for usage that exceeds max
const maxBytes = Math.max(
metrics.storageUsedBytes,
metrics.storageQuotaBytes
);
const isStorageFull = metrics.storageUsedBytes >= metrics.storageQuotaBytes;
const hasQuota = Boolean(metrics.storageQuotaBytes);
const isStorageFull =
hasQuota && metrics.storageUsedBytes >= metrics.storageQuotaBytes;
const renderBar = (value: number, label: string, color: string) => html`
<btrix-meter-bar
value=${(value / metrics.storageUsedBytes) * 100}
@ -259,18 +237,27 @@ export class Dashboard extends LiteElement {
<span>${msg("Storage is Full")}</span>
</div>
`,
() => html`
<sl-format-bytes
value=${maxBytes - metrics.storageUsedBytes}
></sl-format-bytes>
${msg("Available")}
`
() =>
hasQuota
? html`
<sl-format-bytes
value=${metrics.storageQuotaBytes -
metrics.storageUsedBytes}
></sl-format-bytes>
${msg("Available")}
`
: html`
<sl-format-bytes
value=${metrics.storageUsedBytes}
></sl-format-bytes>
${msg("of Data Stored")}
`
)}
</div>
<div class="mb-2">
<btrix-meter
value=${metrics.storageUsedBytes}
max=${maxBytes}
max=${ifDefined(metrics.storageQuotaBytes || undefined)}
valueText=${msg("gigabyte")}
>
${when(metrics.storageUsedCrawls, () =>
@ -308,16 +295,19 @@ export class Dashboard extends LiteElement {
<div class="w-full h-full"></div>
</sl-tooltip>
</div>
<sl-format-bytes
slot="valueLabel"
value=${metrics.storageUsedBytes}
display="narrow"
></sl-format-bytes>
<sl-format-bytes
slot="maxLabel"
value=${metrics.storageQuotaBytes}
display="narrow"
></sl-format-bytes>
${when(
hasQuota,
() => html`<sl-format-bytes
slot="valueLabel"
value=${metrics.storageUsedBytes}
display="narrow"
></sl-format-bytes>
<sl-format-bytes
slot="maxLabel"
value=${metrics.storageQuotaBytes}
display="narrow"
></sl-format-bytes>`
)}
</btrix-meter>
</div>
`;