From aceabb63f5e2b51630108de6f4782d727a15a6d3 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Mon, 9 Feb 2026 11:20:03 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20fix(redis-viewer):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20Redis=20Key=20=E5=88=97=E8=A1=A8=E7=AA=84=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E9=81=AE=E6=8C=A1=E5=B9=B6=E6=94=AF=E6=8C=81=20TTL=20?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=BC=8F=E9=9A=90=E8=97=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 Key 行改为弹性布局,避免 type 标签覆盖名称 - 基于左侧面板宽度阈值自动隐藏 TTL,优先保证名称可读性 - refs #88 --- frontend/src/components/RedisViewer.tsx | 99 +++++++++++++++++++------ 1 file changed, 75 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/RedisViewer.tsx b/frontend/src/components/RedisViewer.tsx index fb8ccfa..c618447 100644 --- a/frontend/src/components/RedisViewer.tsx +++ b/frontend/src/components/RedisViewer.tsx @@ -10,6 +10,10 @@ const { Search } = Input; const KEY_GROUP_DELIMITER = ':'; const EMPTY_SEGMENT_LABEL = '(empty)'; +const REDIS_TREE_KEY_TYPE_WIDTH = 92; +const REDIS_TREE_KEY_TYPE_WIDTH_NARROW = 84; +const REDIS_TREE_KEY_TTL_WIDTH = 92; +const REDIS_TREE_HIDE_TTL_THRESHOLD = 460; interface RedisViewerProps { connectionId: string; @@ -263,7 +267,8 @@ const countGroupLeafNodes = (group: RedisKeyTreeGroup): number => { const buildRedisKeyTree = ( keys: RedisKeyInfo[], formatTTL: (ttl: number) => string, - getTypeColor: (type: string) => string + getTypeColor: (type: string) => string, + showTTL: boolean ): RedisKeyTreeResult => { const root = createTreeGroup('__root__', '__root__'); @@ -330,48 +335,66 @@ const buildRedisKeyTree = ( title: (
- - +
+ {leaf.label} - +
{leaf.keyInfo.type} - - {formatTTL(leaf.keyInfo.ttl)} - + {showTTL && ( + + {formatTTL(leaf.keyInfo.ttl)} + + )}
), }; @@ -424,6 +447,7 @@ const RedisViewer: React.FC = ({ connectionId, redisDB }) => { // 面板宽度状态和 ref - 默认占据 50% 宽度 const [leftPanelWidth, setLeftPanelWidth] = useState('50%'); const leftPanelRef = useRef(null); + const [showTreeKeyTTL, setShowTreeKeyTTL] = useState(true); const [expandedGroupKeys, setExpandedGroupKeys] = useState([]); const getConfig = useCallback(() => { @@ -614,9 +638,36 @@ const RedisViewer: React.FC = ({ connectionId, redisDB }) => { return `${Math.floor(ttl / 86400)}天${Math.floor((ttl % 86400) / 3600)}时`; }; + useEffect(() => { + const target = leftPanelRef.current; + if (!target) return; + + const updateTTLVisibility = (width: number) => { + const nextShowTTL = width > REDIS_TREE_HIDE_TTL_THRESHOLD; + setShowTreeKeyTTL((prev) => (prev === nextShowTTL ? prev : nextShowTTL)); + }; + + updateTTLVisibility(Math.round(target.getBoundingClientRect().width)); + + if (typeof ResizeObserver !== 'undefined') { + const observer = new ResizeObserver((entries) => { + const width = Math.round(entries[0]?.contentRect.width || target.getBoundingClientRect().width); + updateTTLVisibility(width); + }); + observer.observe(target); + return () => observer.disconnect(); + } + + const handleWindowResize = () => { + updateTTLVisibility(Math.round(target.getBoundingClientRect().width)); + }; + window.addEventListener('resize', handleWindowResize); + return () => window.removeEventListener('resize', handleWindowResize); + }, []); + const keyTree = useMemo(() => { - return buildRedisKeyTree(keys, formatTTL, getTypeColor); - }, [keys]); + return buildRedisKeyTree(keys, formatTTL, getTypeColor, showTreeKeyTTL); + }, [keys, showTreeKeyTTL]); const selectedTreeNodeKeys = useMemo(() => { if (!selectedKey) {