Files
Logan.Li ff539b47e0 feat(redis): shared key browser with grouped tree + cursor pagination
New src/features/redis/keyBrowser/ shared by RedisDetailPage keys tab and
SchemaSidebar redis branch (both previously flat one-shot lists):
- keyTree: ':'-separated folder tree with recursive key counts, numeric
  sort, exact-hit pinned at root, local key removal (no full refetch),
  type color dots, readable TTL (45s/5m30s/2d5h)
- useRedisKeyBrowser: cursor state machine + request-sequence guard +
  Map merge on load-more; setter-synced args (Enter right after typing
  no longer races stale render), auto-search on db/instance change
- RedisKeyBrowser: enter-to-scan search bar (SCAN has cost - no debounce,
  opsxdb-style) with clear button, effective type filter, load-more
  button with cursor hint, '已全部加载' end state
- useRedisDbs: real db list from /redis/:id/dbs (cluster -> DB0 banner)
- RedisDetailPage: hash row edits now use field-level HSET/HDEL endpoint
  (preserves other fields + TTL); delete/add update tree locally; CLI
  output renders arrays/objects/errors properly
- SchemaSidebar: redis branch swaps to shared browser (compact mode,
  inline detail preview + insert-command preserved), auto-switches to
  Keys tab for redis instances
- vite dev proxy target overridable via API_PROXY_TARGET (local testing)

Browser-verified: 200/page with load-more (200->400->600), exact hit
badge, keyword auto-expand, key detail panel, queries sidebar
2026-10-26 18:39:38 +08:00

54 lines
1.5 KiB
TypeScript

import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
// 构建指纹:版本 + commit hash + 构建时间(设置页「关于」展示,排障救命)
const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json'), 'utf-8'));
const gitHash = (() => {
try {
return execSync('git rev-parse --short HEAD').toString().trim();
} catch {
return 'unknown';
}
})();
const buildTime = new Date().toISOString();
const APP_VERSION = `${pkg.version}+${gitHash} (${buildTime.slice(0, 16)})`;
export default defineConfig({
base: '/',
define: {
__APP_VERSION__: JSON.stringify(APP_VERSION),
},
plugins: [react()],
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (!id.includes('node_modules')) return;
if (id.includes('react') || id.includes('react-router')) return 'vendor-react';
if (id.includes('@codemirror')) return 'vendor-editor';
if (id.includes('@radix-ui')) return 'vendor-ui';
},
},
},
},
server: {
port: 5173,
strictPort: true,
proxy: {
'/api': {
// 本地联调可用 API_PROXY_TARGET=http://localhost:9001 npm run dev 指向测试实例
target: process.env.API_PROXY_TARGET || 'http://localhost:9000',
changeOrigin: true,
},
},
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
});