mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
fix(settings): show usage limits approaching exhaustion
Provider status tones could hide utilization risk. Display the strongest signal so high usage reaches warning and danger while provider-specific alerts remain visible.
This commit is contained in:
@@ -2,6 +2,7 @@ import { useMemo } from "react";
|
||||
import { Text, View, type StyleProp, type ViewStyle } from "react-native";
|
||||
import { StyleSheet } from "react-native-unistyles";
|
||||
import { clampPct, formatAmount, formatResetLabel } from "./format";
|
||||
import { resolveTone } from "./tone";
|
||||
import type { ProviderUsageBalance, ProviderUsageTone } from "./types";
|
||||
|
||||
interface ResolvedBalance {
|
||||
@@ -41,7 +42,7 @@ function fillToneStyle(tone: ProviderUsageTone) {
|
||||
|
||||
export function ProviderUsageBalanceBar({ balance }: { balance: ProviderUsageBalance }) {
|
||||
const { amountText, usedPct } = resolveBalance(balance);
|
||||
const tone = balance.tone ?? "default";
|
||||
const tone = resolveTone(balance.tone, usedPct);
|
||||
const resetLabel = formatResetLabel(balance.resetsAt);
|
||||
|
||||
const fillStyle = useMemo<StyleProp<ViewStyle>>(
|
||||
|
||||
13
packages/app/src/provider-usage/tone.test.ts
Normal file
13
packages/app/src/provider-usage/tone.test.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveTone } from "./tone";
|
||||
|
||||
describe("provider usage tone", () => {
|
||||
it("shows the strongest risk from provider status and utilization", () => {
|
||||
expect([
|
||||
resolveTone("ok", 5),
|
||||
resolveTone("ok", 70),
|
||||
resolveTone("ok", 99),
|
||||
resolveTone("danger", 5),
|
||||
]).toEqual(["ok", "warning", "danger", "danger"]);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,26 @@
|
||||
import type { ProviderUsageTone } from "./types";
|
||||
|
||||
const TONE_RISK: Record<ProviderUsageTone, number> = {
|
||||
default: 0,
|
||||
ok: 1,
|
||||
warning: 2,
|
||||
danger: 3,
|
||||
};
|
||||
|
||||
export function deriveTone(usedPct: number | null | undefined): ProviderUsageTone {
|
||||
if (usedPct == null) return "default";
|
||||
if (usedPct > 90) return "danger";
|
||||
if (usedPct >= 70) return "warning";
|
||||
return "default";
|
||||
}
|
||||
|
||||
export function resolveTone(
|
||||
providerTone: ProviderUsageTone | undefined,
|
||||
usedPct: number | null | undefined,
|
||||
): ProviderUsageTone {
|
||||
const utilizationTone = deriveTone(usedPct);
|
||||
if (!providerTone || TONE_RISK[utilizationTone] > TONE_RISK[providerTone]) {
|
||||
return utilizationTone;
|
||||
}
|
||||
return providerTone;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useMemo } from "react";
|
||||
import { Text, View, type StyleProp, type ViewStyle } from "react-native";
|
||||
import { StyleSheet } from "react-native-unistyles";
|
||||
import { clampPct, formatPct, formatResetLabel } from "./format";
|
||||
import { deriveTone } from "./tone";
|
||||
import { resolveTone } from "./tone";
|
||||
import type { ProviderUsageTone, ProviderUsageWindow } from "./types";
|
||||
|
||||
function resolveUsedPct(window: ProviderUsageWindow): number | null {
|
||||
@@ -26,7 +26,7 @@ function fillToneStyle(tone: ProviderUsageTone) {
|
||||
|
||||
export function ProviderUsageWindowBar({ window }: { window: ProviderUsageWindow }) {
|
||||
const usedPct = resolveUsedPct(window);
|
||||
const tone = window.tone ?? deriveTone(usedPct);
|
||||
const tone = resolveTone(window.tone, usedPct);
|
||||
|
||||
const fillWidth = clampPct(usedPct ?? 0);
|
||||
const fillStyle = useMemo<StyleProp<ViewStyle>>(
|
||||
|
||||
Reference in New Issue
Block a user