mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-16 09:27:36 +08:00
- Redis Key 搜索默认补全包含匹配并支持 ASCII 大小写不敏感 - Redis 标签页增加连接名与 host 摘要,区分同名 db 标签 - 抽取 inputAutoCap、redisSearchPattern、tabDisplay 共享工具并补充回归测试 - 覆盖连接配置、Redis 搜索、表设计、表概览和数据表筛选输入的自动纠正问题 - 在 macOS 文本输入面板关闭局部毛玻璃,修复输入法切换出现透明框
100 lines
3.3 KiB
TypeScript
100 lines
3.3 KiB
TypeScript
import type { ConnectionConfig, SavedConnection, TabData } from '../types';
|
|
|
|
export const detectConnectionEnvLabel = (connectionName: string): string | null => {
|
|
const tokens = connectionName.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
if (tokens.includes('prod') || tokens.includes('production')) return 'PROD';
|
|
if (tokens.includes('uat')) return 'UAT';
|
|
if (tokens.includes('dev') || tokens.includes('development')) return 'DEV';
|
|
if (tokens.includes('sit')) return 'SIT';
|
|
if (tokens.includes('stg') || tokens.includes('stage') || tokens.includes('staging') || tokens.includes('pre')) return 'STG';
|
|
if (tokens.includes('test') || tokens.includes('qa')) return 'TEST';
|
|
return null;
|
|
};
|
|
|
|
const parseHostOnlyToken = (value: unknown): string[] => {
|
|
const raw = String(value || '').trim();
|
|
if (!raw) {
|
|
return [];
|
|
}
|
|
|
|
let text = raw.replace(/^[a-z][a-z0-9+.-]*:\/\//i, '');
|
|
if (text.includes('/')) {
|
|
text = text.split('/')[0];
|
|
}
|
|
if (text.includes('?')) {
|
|
text = text.split('?')[0];
|
|
}
|
|
if (text.includes('@')) {
|
|
text = text.split('@').pop() || '';
|
|
}
|
|
|
|
return text
|
|
.split(',')
|
|
.map((entry) => {
|
|
const token = entry.trim();
|
|
if (!token) return '';
|
|
if (token.startsWith('[')) {
|
|
const rightBracketIndex = token.indexOf(']');
|
|
if (rightBracketIndex > 0) {
|
|
return token.slice(0, rightBracketIndex + 1).toLowerCase();
|
|
}
|
|
}
|
|
const colonIndex = token.lastIndexOf(':');
|
|
if (colonIndex > 0) {
|
|
return token.slice(0, colonIndex).toLowerCase();
|
|
}
|
|
return token.toLowerCase();
|
|
})
|
|
.filter(Boolean);
|
|
};
|
|
|
|
export const resolveConnectionHostTokens = (config?: ConnectionConfig): string[] => {
|
|
if (!config) {
|
|
return [];
|
|
}
|
|
|
|
return Array.from(new Set([
|
|
...parseHostOnlyToken(config.host),
|
|
...(Array.isArray(config.hosts) ? config.hosts.flatMap((entry) => parseHostOnlyToken(entry)) : []),
|
|
...parseHostOnlyToken(config.uri),
|
|
]));
|
|
};
|
|
|
|
export const resolveConnectionHostSummary = (config?: ConnectionConfig): string => {
|
|
const hosts = resolveConnectionHostTokens(config);
|
|
if (hosts.length === 0) return '';
|
|
if (hosts.length === 1) return hosts[0];
|
|
return `${hosts[0]} +${hosts.length - 1}`;
|
|
};
|
|
|
|
const isRedisTab = (tab: TabData): boolean => {
|
|
return tab.type === 'redis-keys' || tab.type === 'redis-command' || tab.type === 'redis-monitor';
|
|
};
|
|
|
|
const buildRedisBaseTitle = (tab: TabData): string => {
|
|
const dbLabel = `db${tab.redisDB ?? 0}`;
|
|
if (tab.type === 'redis-command') return `命令 - ${dbLabel}`;
|
|
if (tab.type === 'redis-monitor') return `监控 - ${dbLabel}`;
|
|
return dbLabel;
|
|
};
|
|
|
|
export const buildTabDisplayTitle = (tab: TabData, connection?: SavedConnection): string => {
|
|
const connectionName = String(connection?.name || '').trim();
|
|
|
|
if (isRedisTab(tab)) {
|
|
const hostSummary = resolveConnectionHostSummary(connection?.config);
|
|
const identity = [connectionName, hostSummary].filter(Boolean).join(' | ');
|
|
return identity ? `[${identity}] ${buildRedisBaseTitle(tab)}` : buildRedisBaseTitle(tab);
|
|
}
|
|
|
|
if (tab.type !== 'table' && tab.type !== 'design' && tab.type !== 'table-overview') {
|
|
return tab.title;
|
|
}
|
|
if (!connectionName) {
|
|
return tab.title;
|
|
}
|
|
|
|
const prefix = detectConnectionEnvLabel(connectionName) || connectionName;
|
|
return `[${prefix}] ${tab.title}`;
|
|
};
|