From 4954067736294a6989d4db6c653316bdecc9157e Mon Sep 17 00:00:00 2001 From: Yuki Guo Date: Thu, 8 Oct 2026 16:19:29 +0800 Subject: [PATCH] refactor: search bind (#13992) * refactor: search bind * refactor: simplify search persistence --------- Co-authored-by: ssongliu --- .../src/composables/useSearchPersistence.ts | 63 +++++++++++++++++++ frontend/src/store/modules/process.ts | 14 ++++- .../ai/agents/agent/config/tabs/plugins.vue | 8 ++- .../agent/config/tabs/skills/hermes.vue | 8 ++- .../agent/config/tabs/skills/openclaw.vue | 6 ++ frontend/src/views/ai/agents/agent/index.vue | 2 + frontend/src/views/ai/agents/model/index.vue | 2 + frontend/src/views/ai/model/ollama/index.vue | 2 + frontend/src/views/app-store/apps/index.vue | 4 +- .../src/views/app-store/installed/index.vue | 4 +- .../src/views/container/compose/index.vue | 2 + .../src/views/container/container/index.vue | 2 + frontend/src/views/container/image/index.vue | 4 +- .../src/views/container/network/index.vue | 2 + frontend/src/views/container/repo/index.vue | 2 + .../src/views/container/template/index.vue | 2 + frontend/src/views/container/volume/index.vue | 2 + frontend/src/views/cronjob/cronjob/index.vue | 2 + frontend/src/views/cronjob/library/index.vue | 2 + frontend/src/views/database/mongodb/index.vue | 2 + .../views/database/mongodb/remote/index.vue | 2 + frontend/src/views/database/mysql/index.vue | 2 + .../src/views/database/mysql/remote/index.vue | 2 + .../src/views/database/postgresql/index.vue | 2 + .../database/postgresql/remote/index.vue | 2 + .../src/views/database/redis/remote/index.vue | 2 + .../src/views/host/file-management/index.vue | 4 +- .../src/views/host/firewall/docker/index.vue | 2 + .../src/views/host/firewall/forward/index.vue | 2 + .../src/views/host/firewall/rule/index.vue | 2 + frontend/src/views/host/ssh/log/log.vue | 2 + frontend/src/views/host/ssh/session/index.vue | 4 +- frontend/src/views/log/host-system/index.vue | 2 + frontend/src/views/log/login/index.vue | 2 + frontend/src/views/log/operation/index.vue | 2 + .../views/setting/backup-account/index.vue | 4 +- frontend/src/views/setting/snapshot/index.vue | 2 + frontend/src/views/terminal/command/index.vue | 2 + frontend/src/views/terminal/host/index.vue | 2 + frontend/src/views/toolbox/clam/index.vue | 2 + frontend/src/views/toolbox/ftp/index.vue | 2 + .../php/extension-management/index.vue | 3 +- frontend/src/views/website/ssl/index.vue | 4 +- frontend/src/views/website/template/index.vue | 2 + frontend/src/views/website/website/index.vue | 4 +- 45 files changed, 182 insertions(+), 14 deletions(-) create mode 100644 frontend/src/composables/useSearchPersistence.ts diff --git a/frontend/src/composables/useSearchPersistence.ts b/frontend/src/composables/useSearchPersistence.ts new file mode 100644 index 000000000..fcef3d923 --- /dev/null +++ b/frontend/src/composables/useSearchPersistence.ts @@ -0,0 +1,63 @@ +import { storeToRefs } from 'pinia'; +import { watch, type Ref } from 'vue'; +import GlobalStore from '@/store/modules/global'; + +type SearchValue = string | number | undefined; +type SearchFields = Record>; + +export const useSearchPersistence = (page: string, fields: SearchFields, scope?: () => SearchValue) => { + const { currentNode } = storeToRefs(GlobalStore()); + const defaults = Object.fromEntries(Object.entries(fields).map(([name, field]) => [name, field.value])); + let initialized = false; + let restoring = false; + let activeKey: string | undefined; + + watch( + () => { + const context = scope?.(); + if (scope && context === undefined) return undefined; + return `1panel:search:v1:${JSON.stringify([currentNode.value, page, context ?? ''])}`; + }, + (key) => { + activeKey = key; + let saved: Record = {}; + try { + const parsed = activeKey ? JSON.parse(localStorage.getItem(activeKey) || '{}') : {}; + if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) saved = parsed; + } catch {} + restoring = true; + for (const [name, field] of Object.entries(fields)) { + const value = saved[name]; + const initial = defaults[name]; + let fallback = initial; + if (initialized) { + fallback = typeof initial === 'string' ? '' : undefined; + } + const valid = + (typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value))) && + (fallback === undefined || typeof value === typeof fallback); + if (value === null) { + field.value = typeof initial === 'string' ? '' : undefined; + } else if (valid) { + field.value = value as SearchValue; + } else { + field.value = fallback; + } + } + restoring = false; + initialized = true; + }, + { immediate: true, flush: 'sync' }, + ); + + watch( + () => Object.fromEntries(Object.entries(fields).map(([name, field]) => [name, field.value ?? null])), + (value) => { + if (restoring || !activeKey) return; + try { + localStorage.setItem(activeKey, JSON.stringify(value)); + } catch {} + }, + { flush: 'sync' }, + ); +}; diff --git a/frontend/src/store/modules/process.ts b/frontend/src/store/modules/process.ts index f2795fd5f..13a5a4ece 100644 --- a/frontend/src/store/modules/process.ts +++ b/frontend/src/store/modules/process.ts @@ -1,5 +1,6 @@ +import { useSearchPersistence } from '@/composables/useSearchPersistence'; import { defineStore } from 'pinia'; -import { ref, reactive } from 'vue'; +import { ref, reactive, toRef } from 'vue'; import { MsgError } from '@/utils/message'; import { checkStreamAuth } from '@/utils/stream-auth'; @@ -46,6 +47,17 @@ export const ProcessStore = defineStore('ProcessStore', () => { port: undefined, }); + useSearchPersistence('host/process/process', { + pid: toRef(psSearch, 'pid'), + name: toRef(psSearch, 'name'), + username: toRef(psSearch, 'username'), + }); + useSearchPersistence('host/process/network', { + processID: toRef(netSearch, 'processID'), + processName: toRef(netSearch, 'processName'), + port: toRef(netSearch, 'port'), + }); + let pendingRequestType: 'ps' | 'net' | null = null; let queuedRequestType: 'ps' | 'net' | null = null; diff --git a/frontend/src/views/ai/agents/agent/config/tabs/plugins.vue b/frontend/src/views/ai/agents/agent/config/tabs/plugins.vue index 5187d3580..1a7994868 100644 --- a/frontend/src/views/ai/agents/agent/config/tabs/plugins.vue +++ b/frontend/src/views/ai/agents/agent/config/tabs/plugins.vue @@ -172,6 +172,7 @@