diff --git a/ui/package-lock.json b/ui/package-lock.json
index 66bac5fb..66ae4b88 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -14,6 +14,7 @@
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-router": "^7.13.1",
+ "swagger-ui-dist": "^5.32.0",
"uplot": "^1.6.32",
"zustand": "^5.0.11"
},
@@ -941,6 +942,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@scarf/scarf": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
+ "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0"
+ },
"node_modules/@tanstack/query-core": {
"version": "5.90.20",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz",
@@ -3027,6 +3035,15 @@
"node": ">=8"
}
},
+ "node_modules/swagger-ui-dist": {
+ "version": "5.32.0",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.32.0.tgz",
+ "integrity": "sha512-nKZB0OuDvacB0s/lC2gbge+RigYvGRGpLLMWMFxaTUwfM+CfndVk9Th2IaTinqXiz6Mn26GK2zriCpv6/+5m3Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@scarf/scarf": "=1.4.0"
+ }
+ },
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
diff --git a/ui/package.json b/ui/package.json
index 5841cc02..96718422 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -18,6 +18,7 @@
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-router": "^7.13.1",
+ "swagger-ui-dist": "^5.32.0",
"uplot": "^1.6.32",
"zustand": "^5.0.11"
},
diff --git a/ui/src/components/layout/TopNav.module.css b/ui/src/components/layout/TopNav.module.css
index cac7dd1f..d87c9cb0 100644
--- a/ui/src/components/layout/TopNav.module.css
+++ b/ui/src/components/layout/TopNav.module.css
@@ -61,6 +61,30 @@
gap: 16px;
}
+.utilLink {
+ font-family: var(--font-mono);
+ font-size: 11px;
+ font-weight: 500;
+ color: var(--text-muted);
+ text-decoration: none;
+ padding: 4px 10px;
+ border-radius: 99px;
+ border: 1px solid var(--border);
+ transition: all 0.15s;
+}
+
+.utilLink:hover {
+ color: var(--text-primary);
+ border-color: var(--text-muted);
+}
+
+.utilLinkActive {
+ composes: utilLink;
+ color: var(--amber);
+ border-color: rgba(245, 158, 11, 0.3);
+ background: var(--amber-glow);
+}
+
.envBadge {
font-family: var(--font-mono);
font-size: 11px;
diff --git a/ui/src/components/layout/TopNav.tsx b/ui/src/components/layout/TopNav.tsx
index e2e86d94..89f27dfa 100644
--- a/ui/src/components/layout/TopNav.tsx
+++ b/ui/src/components/layout/TopNav.tsx
@@ -28,11 +28,6 @@ export function TopNav() {
Applications
-
-
- API
-
-
{roles.includes('ADMIN') && (
isActive ? styles.navLinkActive : styles.navLink}>
@@ -43,6 +38,9 @@ export function TopNav() {
+
isActive ? styles.utilLinkActive : styles.utilLink} title="API Documentation">
+ API
+
{import.meta.env.VITE_ENV_NAME || 'DEV'}