-
Clusters
+
Clusters
{Object.entries(clusterGroups).map(([clusterId, clusterConnections]) => (
- Instances
+ Instances
{standaloneConnections.map(({ connectionId, connection }) => (
-
+
+
+
{lastConnectionTime && lastConnectionTime.event === CONNECTED && (
-
+
Last connected: {new Date(lastConnectionTime.timestamp).toLocaleString()}
-
+
)}
{/* action buttons */}
@@ -104,25 +107,27 @@ export const ConnectionEntry = ({
-
+
+
+
{connection.connectionDetails.alias && (
-
+
({label})
- )}
+ )}
{lastConnectionTime && lastConnectionTime.event === CONNECTED && (
-
+
Last connected: {new Date(lastConnectionTime.timestamp).toLocaleString()}
-
+
)}
diff --git a/apps/frontend/src/components/connection/__tests__/text-truncation.test.tsx b/apps/frontend/src/components/connection/__tests__/text-truncation.test.tsx
index 45a1f63f..4013d69f 100644
--- a/apps/frontend/src/components/connection/__tests__/text-truncation.test.tsx
+++ b/apps/frontend/src/components/connection/__tests__/text-truncation.test.tsx
@@ -81,12 +81,12 @@ describe("Text Truncation Improvements", () => {
,
)
- // Check for last connection time span with truncate class
- const lastConnectionSpans = container.querySelectorAll("span.truncate")
- const hasLastConnectionSpan = Array.from(lastConnectionSpans).some((span) =>
- span.textContent?.includes("Last connected:"),
+ // Check for last connection time in Typography component (renders as p by default)
+ const lastConnectionElements = container.querySelectorAll("p")
+ const hasLastConnectionElement = Array.from(lastConnectionElements).some((p) =>
+ p.textContent?.includes("Last connected:"),
)
- expect(hasLastConnectionSpan).toBe(true)
+ expect(hasLastConnectionElement).toBe(true)
})
it("should apply truncate class and title to alias display", () => {
@@ -100,12 +100,12 @@ describe("Text Truncation Improvements", () => {
,
)
- // Check for alias span with truncate class and title
- const aliasSpans = container.querySelectorAll("span.truncate[title]")
- const hasAliasSpan = Array.from(aliasSpans).some((span) =>
- span.textContent?.includes("(") && span.textContent?.includes(")"),
+ // Check for alias in Typography component with truncate and title
+ const aliasElements = container.querySelectorAll("p.truncate[title]")
+ const hasAliasElement = Array.from(aliasElements).some((p) =>
+ p.textContent?.includes("(") && p.textContent?.includes(")"),
)
- expect(hasAliasSpan).toBe(true)
+ expect(hasAliasElement).toBe(true)
})
})
@@ -161,13 +161,13 @@ describe("Text Truncation Improvements", () => {
,
)
- // Since there are no connected instances, cluster name should be an h3 element
- const clusterNameElement = container.querySelector("h3[title]")
+ // Since there are no connected instances, cluster name should be a code element with Typography
+ const clusterNameElement = container.querySelector("code[title]")
expect(clusterNameElement).toBeInTheDocument()
expect(clusterNameElement).toHaveAttribute("title")
- // Check that it has the ellipsis CSS classes
- expect(clusterNameElement).toHaveClass("overflow-hidden", "text-ellipsis", "whitespace-nowrap")
+ // Check that it has truncate class
+ expect(clusterNameElement).toHaveClass("truncate")
})
it("should apply truncate class and title to instance count text", () => {
@@ -190,10 +190,10 @@ describe("Text Truncation Improvements", () => {
,
)
- // Check for instance count div with truncate class and title
- const instanceCountElements = container.querySelectorAll("div.truncate[title]")
- const hasInstanceCountElement = Array.from(instanceCountElements).some((div) =>
- div.textContent?.includes("instance"),
+ // Check for instance count in Typography component with code variant (renders as
element) with truncate and title
+ const instanceCountElements = container.querySelectorAll("code.truncate[title]")
+ const hasInstanceCountElement = Array.from(instanceCountElements).some((code) =>
+ code.textContent?.includes("instance"),
)
expect(hasInstanceCountElement).toBe(true)
})
diff --git a/apps/frontend/src/components/dashboard/Dashboard.tsx b/apps/frontend/src/components/dashboard/Dashboard.tsx
index 9a789ba6..2d3675a6 100644
--- a/apps/frontend/src/components/dashboard/Dashboard.tsx
+++ b/apps/frontend/src/components/dashboard/Dashboard.tsx
@@ -15,6 +15,7 @@ import { Panel } from "../ui/panel"
import { Input } from "../ui/input"
import { StatCard } from "../ui/stat-card"
import RouteContainer from "../ui/route-container"
+import { Typography } from "../ui/typography"
import { selectData } from "@/state/valkey-features/info/infoSelectors.ts"
export function Dashboard() {
@@ -30,7 +31,9 @@ export function Dashboard() {
title="Dashboard"
/>
- Loading metrics…
+
+ Loading metrics…
+
)
diff --git a/apps/frontend/src/components/ui/accordion.tsx b/apps/frontend/src/components/ui/accordion.tsx
index 92bcbe83..8ebc6270 100644
--- a/apps/frontend/src/components/ui/accordion.tsx
+++ b/apps/frontend/src/components/ui/accordion.tsx
@@ -3,6 +3,7 @@ import { CircleChevronDown, CircleChevronUp, Dot } from "lucide-react"
import { formatMetricValue, type ValueType } from "@common/src/format-metric-value"
import { TooltipProvider } from "@radix-ui/react-tooltip"
import { TooltipIcon } from "./tooltip-icon"
+import { Typography } from "./typography"
interface AccordionProps {
accordionName?: string;
@@ -66,15 +67,17 @@ export default function Accordion({ accordionName, accordionItems, valueType = "
- {accordionName}
+
+ {accordionName}
-
-
+
+
{searchQuery.trim() && filteredItemCount !== itemCount ? (
<>{filteredItemCount} of {itemCount} {itemCount === 1 ? "metric" : "metrics"}>
) : (
<>{itemCount} {itemCount === 1 ? "metric" : "metrics"}>
- )}
+ )}
+
@@ -86,12 +89,15 @@ export default function Accordion({ accordionName, accordionItems, valueType = "
{Object.entries(filteredItems).map(([key, value]) => (
- {formatKey(key)}
+
+
+ {formatKey(key)}
+
{singleMetricDescriptions[key] && (
)}
- {formatMetricValue(key, value, valueType)}
+ {formatMetricValue(key, value, valueType)}
))}
diff --git a/apps/frontend/src/components/ui/app-header.tsx b/apps/frontend/src/components/ui/app-header.tsx
index b55493e5..6d23b5e2 100644
--- a/apps/frontend/src/components/ui/app-header.tsx
+++ b/apps/frontend/src/components/ui/app-header.tsx
@@ -3,8 +3,8 @@ import { useSelector } from "react-redux"
import { useState, useRef, useEffect, type ReactNode } from "react"
import { CircleChevronDown, CircleChevronUp, Dot, CornerDownRight } from "lucide-react"
import { CONNECTED } from "@common/src/constants.ts"
-import { Title } from "./title"
import { Badge } from "./badge"
+import { Typography } from "./typography"
import type { RootState } from "@/store.ts"
import { selectConnectionDetails } from "@/state/valkey-features/connection/connectionSelectors.ts"
import { selectCluster } from "@/state/valkey-features/cluster/clusterSelectors"
@@ -58,9 +58,10 @@ function AppHeader({ title, icon, className }: AppHeaderProps) {
<>
{id && !clusterId ? (
-
+
+ {icon}
{title}
-
+
{alias ? alias : `${username}@${host}:${port}`}
@@ -68,19 +69,23 @@ function AppHeader({ title, icon, className }: AppHeaderProps) {
) : (
-
+
+ {icon}
{title}
-
+
-
+
{id}
-
+