From 8a11242d7f7c77925d0a0ddd936c37760d23352d Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Wed, 25 Mar 2026 12:08:05 -0300 Subject: [PATCH 1/2] feat(ui): group limits dashboard connections by tag field to improve configuration visibility --- .../usage/components/ProviderLimits/index.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx b/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx index 1329694d9d..b78b8412f2 100644 --- a/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx +++ b/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx @@ -334,11 +334,21 @@ export default function ProviderLimits() { if (groupBy !== "environment") return null; const groups = new Map(); for (const conn of visibleConnections) { - const key = conn.group || t("ungrouped"); + const key = (conn.providerSpecificData?.tag as string | undefined)?.trim() || t("ungrouped"); if (!groups.has(key)) groups.set(key, []); groups.get(key).push(conn); } - return groups; + + // Convert to sorted array based on tag string (ungrouped at the end) + const sortedGroups = new Map( + [...groups.entries()].sort(([a], [b]) => { + if (a === t("ungrouped")) return 1; + if (b === t("ungrouped")) return -1; + return a.localeCompare(b); + }) + ); + + return sortedGroups; }, [groupBy, visibleConnections, t]); const handleSetGroupBy = (value: "none" | "environment") => { @@ -359,7 +369,10 @@ export default function ProviderLimits() { useEffect(() => { if (typeof window === "undefined") return; const hasSaved = localStorage.getItem(LS_GROUP_BY) !== null; - if (!hasSaved && connections.some((c) => c.group)) { + if ( + !hasSaved && + connections.some((c) => (c.providerSpecificData?.tag as string | undefined)?.trim()) + ) { setGroupBy("environment"); } }, [connections]); From 95f8599dc2070fde7d404c099e8844b4b6e3c885 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Wed, 25 Mar 2026 12:11:46 -0300 Subject: [PATCH 2/2] chore(release): v3.0.5 --- CHANGELOG.md | 8 ++++++++ docs/openapi.yaml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b1e7ecdf..7636b8e369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ --- +## [3.0.5] — 2026-03-25 + +### ✨ New Features + +- **Limits UI:** Added tag grouping feature to the connections dashboard to improve visual organization for accounts with custom tags. + +--- + ## [3.0.4] — 2026-03-25 ### 🐛 Bug Fixes diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 5c332374d2..ebc9a4b796 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: OmniRoute API - version: 3.0.4 + version: 3.0.5 description: | OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible endpoint that routes requests to multiple AI providers with load balancing, diff --git a/package-lock.json b/package-lock.json index f3af5573f4..99676f14df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "omniroute", - "version": "3.0.4", + "version": "3.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omniroute", - "version": "3.0.4", + "version": "3.0.5", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index 9a7a78d250..f5c3a32195 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "omniroute", - "version": "3.0.4", + "version": "3.0.5", "description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.", "type": "module", "bin": {