diff --git a/src/main/ipc-handlers.ts b/src/main/ipc-handlers.ts index 344f99b..95aaa51 100644 --- a/src/main/ipc-handlers.ts +++ b/src/main/ipc-handlers.ts @@ -207,4 +207,10 @@ export function registerIpcHandlers(): void { ipcMain.handle('redis:existsKey', async (_e, id: string, key: string) => { return redisService.existsKey(id, key) }) + ipcMain.handle('redis:ping', async (_e, id: string) => { + return redisService.ping(id) + }) + ipcMain.handle('redis:isConnected', (_e, id: string) => { + return redisService.isConnected(id) + }) } diff --git a/src/main/redis-service.ts b/src/main/redis-service.ts index 18d08fd..79670b8 100644 --- a/src/main/redis-service.ts +++ b/src/main/redis-service.ts @@ -337,3 +337,14 @@ export async function existsKey(id: string, key: string): Promise { if (!client) throw new Error(`Client ${id} not found`) return (await client.exists(key)) === 1 } + +export async function ping(id: string): Promise { + const client = clients.get(id) + if (!client) throw new Error(`Client ${id} not found`) + return client.ping() +} + +export function isConnected(id: string): boolean { + const client = clients.get(id) + return client?.status === 'ready' +} diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index 94d90c9..d2bd911 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -94,6 +94,8 @@ export interface ElectronAPI { streamDel: (id: string, key: string, ids: string[]) => Promise renameKey: (id: string, oldKey: string, newKey: string) => Promise existsKey: (id: string, key: string) => Promise + ping: (id: string) => Promise + isConnected: (id: string) => Promise } } diff --git a/src/preload/index.ts b/src/preload/index.ts index 2ba0c6e..271baa1 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -110,6 +110,10 @@ const electronAPI = { ipcRenderer.invoke('redis:renameKey', id, oldKey, newKey), existsKey: (id: string, key: string): Promise => ipcRenderer.invoke('redis:existsKey', id, key), + ping: (id: string): Promise => + ipcRenderer.invoke('redis:ping', id), + isConnected: (id: string): Promise => + ipcRenderer.invoke('redis:isConnected', id), }, } diff --git a/src/renderer/src/components/KeyList.vue b/src/renderer/src/components/KeyList.vue index 26aa130..75fcbad 100644 --- a/src/renderer/src/components/KeyList.vue +++ b/src/renderer/src/components/KeyList.vue @@ -9,10 +9,18 @@ const keyStore = useKeyStore() const connStore = useConnectionStore() const filterText = ref('') +const patternInput = ref('*') const showTree = ref(false) const multiSelect = ref(false) const selectedKeys = ref>(new Set()) +function applyPattern() { + keyStore.pattern = patternInput.value || '*' + if (connStore.activeId) { + keyStore.scanKeys(connStore.activeId, '0', true) + } +} + async function loadMore() { if (!connStore.activeId) return await keyStore.scanKeys(connStore.activeId, keyStore.scanCursor) @@ -21,6 +29,7 @@ async function loadMore() { async function refreshKeys() { if (!connStore.activeId) return selectedKeys.value.clear() + keyStore.pattern = patternInput.value || '*' await keyStore.scanKeys(connStore.activeId, '0', true) } @@ -59,6 +68,12 @@ function toggleMultiSelect() { } } +function deselectAll() { + selectedKeys.value.clear() + keyStore.selectedKey = null + keyStore.keyData = null +} + const filteredKeys = ref([]) watch( () => keyStore.keys, @@ -75,17 +90,34 @@ watch(filterText, (val) => { ? keyStore.keys.filter(k => k.name.includes(val)).map(k => k.name) : keyStore.keys.map(k => k.name) }) + +defineExpose({ deselectAll })