feat(providers): add status filter to providers dashboard

Adds a client-side status filter (All / Active / Inactive / No
connection) to the Providers page, applied over the already-fetched
provider + connection list. Status derives from getProviderStats
(total, allDisabled); noAuth providers count as Active. Filter composes
with the existing search across all provider sections. Part of #3699.
This commit is contained in:
openhands
2026-09-03 09:38:05 +07:00
parent ac98dd9d32
commit d1d4e0f02b
3 changed files with 119 additions and 10 deletions

View File

@@ -0,0 +1,52 @@
import { describe, expect, it } from "vitest";
import {
STATUS_FILTER_OPTIONS,
getConnectionStatus,
matchesStatusFilter,
} from "@/app/(dashboard)/dashboard/providers/utils.js";
describe("providers status filter", () => {
it("exposes all/active/inactive/none options", () => {
expect(STATUS_FILTER_OPTIONS.map((o) => o.value)).toEqual([
"all",
"active",
"inactive",
"none",
]);
});
it("classifies a provider with no connections as none", () => {
expect(getConnectionStatus({ total: 0, allDisabled: false })).toBe("none");
});
it("classifies a provider whose only connections are disabled as inactive", () => {
expect(getConnectionStatus({ total: 2, allDisabled: true })).toBe(
"inactive",
);
});
it("classifies a provider with at least one enabled connection as active", () => {
expect(getConnectionStatus({ total: 1, allDisabled: false })).toBe(
"active",
);
});
it("treats noAuth providers as active even with no stored connection", () => {
expect(getConnectionStatus({ total: 0, allDisabled: false }, true)).toBe(
"active",
);
});
it("matchesStatusFilter always passes for 'all'", () => {
expect(matchesStatusFilter("all", { total: 0, allDisabled: false })).toBe(
true,
);
});
it("matchesStatusFilter compares against the derived status", () => {
const disabledStats = { total: 3, allDisabled: true };
expect(matchesStatusFilter("inactive", disabledStats)).toBe(true);
expect(matchesStatusFilter("active", disabledStats)).toBe(false);
expect(matchesStatusFilter("none", disabledStats)).toBe(false);
});
});