Skip to content

feat(dashboard): per-provider dropdown filter on the quota dashboard - #4495

Merged
diegosouzapw merged 1 commit into
release/v3.8.33from
feat/port-pr-769-quota-dashboard-filter
Jun 21, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.33from
feat/port-pr-769-quota-dashboard-filter

Conversation

@diegosouzapw

@diegosouzapw diegosouzapw commented Jun 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

Port of an upstream fix by @DEYLNN, adapted to OmniRoute's TypeScript ProviderLimits and its richer existing filter UX.

The Quota dashboard (/dashboard/usage) now has a Provider dropdown alongside the existing Status / Type / Tier / Env filters. Selecting a provider narrows the visible accounts to that provider only; the choice persists in localStorage (omniroute:limits:providerFilter) and the dropdown auto-falls back to "all" when the persisted key no longer matches a connection in the current session. The dropdown only renders when there are ≥2 distinct providers in view, so single-provider setups stay clean.

What I ported vs what I skipped on purpose

Upstream PR #769 adds two things — I ported the first and intentionally skipped the second:

Upstream PR #769 OmniRoute
"All providers" dropdown ✅ Ported — added as a 5th filter dimension alongside the existing Status / Type / Tier / Env chips.
"Expiring first" sort toggle ⏭️ Skipped (SKIP-DUP) — visibleConnections in index.tsx already always sorts by status group (critical → alert → ok → empty) and tie-breaks by getSoonestResetMs within each group. Adding the toggle would either be redundant or, when off, regress the existing always-on behavior.

Implementation notes

  • The provider key set is derived from sortedConnections, which is already filtered by USAGE_SUPPORTED_PROVIDERS + OAuth/api-key auth upstream, so the dropdown never lists providers the user can't actually inspect.
  • Labels reuse the local PROVIDER_LABEL map (same source the existing per-card headers use), with a graceful fallback to the raw provider key.
  • Sorting uses the existing i18n-aware compareTr helper from @/shared/utils/turkishText so the dropdown follows the active locale's collation.
  • Provider filter is evaluated first in the visibleConnections predicate (cheapest check, prunes the largest fraction of the work).

Testability seam

Filter + option-builder logic was extracted from the inline useMemo into two pure helpers in ProviderLimits/utils.tsx:

  • matchesProviderFilter(connection, providerFilter)
  • buildProviderOptions(connections, compare?)

Both are exercised by 8 cases in tests/unit/provider-limits-provider-filter.test.ts (Node native test runner). This makes the predicates regression-safe without rendering React, and keeps the index.tsx useMemo a thin wire rather than the source of truth.

Test plan

  • node --import tsx/esm --test tests/unit/provider-limits-provider-filter.test.ts — 8/8 pass
  • node --import tsx/esm --test tests/unit/t13-stale-quota-display.test.ts tests/unit/provider-limits-proxy-fail-closed.test.ts — nearby tests still 5/5 (no regression in adjacent quota code)
  • npm run typecheck:core — clean
  • npx eslint on the 3 touched files (index.tsx, utils.tsx, the new test) — clean
  • Manual UI check on a multi-provider setup (the dropdown's render gate providerOptions.length > 1 is only exercised live)

Attribution

  • Original author: @DEYLNN (Zhen) — credited via Co-authored-by: trailer

Closes nothing (no OmniRoute issue tracks this — driven by upstream port).

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a provider dropdown filter for the quota dashboard, allowing users to filter connections by provider. It adds state management, local storage persistence, helper functions, and comprehensive unit tests. The reviewer identified a high-severity UI/state desynchronization bug where a stale provider filter loaded from localStorage could cause the connection list to appear empty while the dropdown falsely displays "All providers". A code suggestion was provided to resolve the active provider filter inside visibleConnections using the same fallback logic as the dropdown.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 671 to +673
const visibleConnections = useMemo(() => {
const filtered = sortedConnections.filter((conn) => {
if (!matchesProviderFilter(conn, providerFilter)) return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There is a potential UI/state desynchronization bug when a stale provider filter is loaded from localStorage (e.g., if a provider was used in a previous session but is no longer present in the current session's connections).

In the dropdown UI, the <select> element falls back to "all" if the persisted providerFilter is not present in providerOptions:

value={
  providerFilter === "all" || providerOptions.includes(providerFilter)
    ? providerFilter
    : "all"
}

However, visibleConnections filters using the raw providerFilter state directly:

if (!matchesProviderFilter(conn, providerFilter)) return false;

This causes the list of connections to be completely empty (since no connection matches the stale provider), while the dropdown UI falsely displays "All providers" as selected.

To fix this, we should resolve the active provider filter inside visibleConnections using the same fallback logic (by checking if the filter is "all" or exists in the current connections).

Suggested change
const visibleConnections = useMemo(() => {
const filtered = sortedConnections.filter((conn) => {
if (!matchesProviderFilter(conn, providerFilter)) return false;
const visibleConnections = useMemo(() => {
const activeProvider =
providerFilter === "all" || sortedConnections.some((c) => c.provider === providerFilter)
? providerFilter
: "all";
const filtered = sortedConnections.filter((conn) => {
if (!matchesProviderFilter(conn, activeProvider)) return false;

@diegosouzapw diegosouzapw changed the title feat(dashboard): per-provider dropdown filter on the quota dashboard (port of #769) feat(dashboard): per-provider dropdown filter on the quota dashboard Jun 21, 2026
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.32 to release/v3.8.33 June 21, 2026 14:02
Adds a single-select Provider dropdown alongside the existing
Status/Type/Tier/Env filters on the Quota dashboard. Selecting a
provider narrows visible accounts to that provider only; the choice
persists in localStorage (`omniroute:limits:providerFilter`) and
auto-falls back to "All providers" when the persisted key no longer
matches a connection in view. The dropdown only renders when there
are >=2 distinct providers so single-provider setups stay clean.

The provider key set is derived from `sortedConnections` (already
USAGE_SUPPORTED_PROVIDERS-filtered and OAuth/api-key-filtered upstream)
and the dropdown labels reuse the local `PROVIDER_LABEL` map, so the
list never includes providers the user can't actually inspect.

The upstream PR also added an "Expiring first" sort toggle. Skipped on
purpose: `visibleConnections` already always sorts by status group
(critical -> alert -> ok -> empty) and tie-breaks by soonest
`getSoonestResetMs` within each group, so the toggle would either be
redundant or weaker than the existing always-on behavior.

Filter + dropdown-options logic extracted to pure helpers in
`utils.tsx` (`matchesProviderFilter`, `buildProviderOptions`) so the
predicates are exercised by a Node native-runner unit test instead of
living inline in a React-only `useMemo`.

Inspired-by: decolua/9router#769
Co-authored-by: Zhen <zhen@dkzhen.org>
@diegosouzapw
diegosouzapw force-pushed the feat/port-pr-769-quota-dashboard-filter branch from a1497d0 to 4591199 Compare June 21, 2026 17:09
@diegosouzapw
diegosouzapw merged commit dac9f7d into release/v3.8.33 Jun 21, 2026
3 checks passed
@diegosouzapw diegosouzapw mentioned this pull request Jun 22, 2026
@diegosouzapw
diegosouzapw deleted the feat/port-pr-769-quota-dashboard-filter branch June 22, 2026 02:48
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…iegosouzapw#4495)

Rebuilt onto release/v3.8.33 (squash-base-stale). Integrated into release/v3.8.33.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant