feat: Redis browser overhaul — Navicat-style table, editing, and pagination
- Unified key table with columns: key, type, value preview, size, TTL - Top-bottom split layout: key table above, value detail below - Virtual scrolling via RecycleScroller for large key sets - ZSet editing: add/remove members with scores - TTL inline editing: click badge to modify expiration - Batch key deletion with checkbox selection - Paginated loading for Hash/Set/ZSet/List values (HSCAN/SSCAN/ZSCAN) - Debounced auto-search (400ms) for key filtering - Value previews fetched during key scan for instant display
This commit is contained in:
1 parent
d6e273e136
commit
1a1f128f2b
11 files changed
+960
-212
No files matched your search
@@ -93,6 +93,11 @@ export const redisListPush = forward("redisListPush");
|
||||
export const redisListRemove = forward("redisListRemove");
|
||||
export const redisSetAdd = forward("redisSetAdd");
|
||||
export const redisSetRemove = forward("redisSetRemove");
|
||||
export const redisZadd = forward("redisZadd");
|
||||
export const redisZrem = forward("redisZrem");
|
||||
export const redisSetTtl = forward("redisSetTtl");
|
||||
export const redisDeleteKeys = forward("redisDeleteKeys");
|
||||
export const redisLoadMore = forward("redisLoadMore");
|
||||
|
||||
// MongoDB
|
||||
export const mongoListDatabases = forward("mongoListDatabases");
|
||||
|
||||
@@ -498,6 +498,39 @@ export async function redisSetRemove(connectionId: string, db: number, keyRaw: s
|
||||
return post("/api/redis/set-remove", { connectionId, db, keyRaw, member });
|
||||
}
|
||||
|
||||
export async function redisZadd(
|
||||
connectionId: string,
|
||||
db: number,
|
||||
keyRaw: string,
|
||||
member: string,
|
||||
score: number,
|
||||
): Promise<void> {
|
||||
return post("/api/redis/zadd", { connectionId, db, keyRaw, member, score });
|
||||
}
|
||||
|
||||
export async function redisZrem(connectionId: string, db: number, keyRaw: string, member: string): Promise<void> {
|
||||
return post("/api/redis/zrem", { connectionId, db, keyRaw, member });
|
||||
}
|
||||
|
||||
export async function redisSetTtl(connectionId: string, db: number, keyRaw: string, ttl: number): Promise<void> {
|
||||
return post("/api/redis/set-ttl", { connectionId, db, keyRaw, ttl });
|
||||
}
|
||||
|
||||
export async function redisDeleteKeys(connectionId: string, db: number, keyRaws: string[]): Promise<number> {
|
||||
return post("/api/redis/delete-keys", { connectionId, db, keyRaws });
|
||||
}
|
||||
|
||||
export async function redisLoadMore(
|
||||
connectionId: string,
|
||||
db: number,
|
||||
keyRaw: string,
|
||||
keyType: string,
|
||||
cursor: number,
|
||||
count: number,
|
||||
): Promise<RedisValue> {
|
||||
return post("/api/redis/load-more", { connectionId, db, keyRaw, keyType, cursor, count });
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// MongoDB
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -9,6 +9,8 @@ export interface RedisKeyTreeLeafNode {
|
||||
db: number;
|
||||
keyType: string;
|
||||
ttl: number;
|
||||
size: number;
|
||||
valuePreview: string;
|
||||
pathSegments: string[];
|
||||
}
|
||||
|
||||
@@ -67,6 +69,8 @@ export function buildRedisKeyTree(keys: RedisKeyInfo[], db: number): RedisKeyTre
|
||||
db,
|
||||
keyType: key.key_type,
|
||||
ttl: key.ttl,
|
||||
size: key.size,
|
||||
valuePreview: key.value_preview,
|
||||
pathSegments,
|
||||
});
|
||||
continue;
|
||||
@@ -101,6 +105,8 @@ export function buildRedisKeyTree(keys: RedisKeyInfo[], db: number): RedisKeyTre
|
||||
db,
|
||||
keyType: key.key_type,
|
||||
ttl: key.ttl,
|
||||
size: key.size,
|
||||
valuePreview: key.value_preview,
|
||||
pathSegments,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -262,6 +262,8 @@ export interface RedisKeyInfo {
|
||||
key_raw: string;
|
||||
key_type: string;
|
||||
ttl: number;
|
||||
size: number;
|
||||
value_preview: string;
|
||||
}
|
||||
|
||||
export interface RedisValue {
|
||||
@@ -271,6 +273,8 @@ export interface RedisValue {
|
||||
ttl: number;
|
||||
value_is_binary: boolean;
|
||||
value: any;
|
||||
total?: number;
|
||||
scan_cursor?: number;
|
||||
}
|
||||
|
||||
export interface RedisScanResult {
|
||||
@@ -340,6 +344,39 @@ export async function redisSetRemove(connectionId: string, db: number, keyRaw: s
|
||||
return invoke("redis_set_remove", { connectionId, db, keyRaw, member });
|
||||
}
|
||||
|
||||
export async function redisZadd(
|
||||
connectionId: string,
|
||||
db: number,
|
||||
keyRaw: string,
|
||||
member: string,
|
||||
score: number,
|
||||
): Promise<void> {
|
||||
return invoke("redis_zadd", { connectionId, db, keyRaw, member, score });
|
||||
}
|
||||
|
||||
export async function redisZrem(connectionId: string, db: number, keyRaw: string, member: string): Promise<void> {
|
||||
return invoke("redis_zrem", { connectionId, db, keyRaw, member });
|
||||
}
|
||||
|
||||
export async function redisSetTtl(connectionId: string, db: number, keyRaw: string, ttl: number): Promise<void> {
|
||||
return invoke("redis_set_ttl", { connectionId, db, keyRaw, ttl });
|
||||
}
|
||||
|
||||
export async function redisDeleteKeys(connectionId: string, db: number, keyRaws: string[]): Promise<number> {
|
||||
return invoke("redis_delete_keys", { connectionId, db, keyRaws });
|
||||
}
|
||||
|
||||
export async function redisLoadMore(
|
||||
connectionId: string,
|
||||
db: number,
|
||||
keyRaw: string,
|
||||
keyType: string,
|
||||
cursor: number,
|
||||
count: number,
|
||||
): Promise<RedisValue> {
|
||||
return invoke("redis_load_more", { connectionId, db, keyRaw, keyType, cursor, count });
|
||||
}
|
||||
|
||||
// --- MongoDB ---
|
||||
export interface MongoDocumentResult {
|
||||
documents: any[];
|
||||
|
||||
Reference in new issue
Block a user