This is an automated email from the ASF dual-hosted git repository.

wu-sheng pushed a commit to branch refactor/decompose-large-files
in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git

commit 0cff26a5cc4cc33a9fdb11941038b0fc4aabf528
Author: Wu Sheng <[email protected]>
AuthorDate: Sat Jun 27 01:25:17 2026 +0800

    fix(ui): close gap-review findings — stale state + missing Escape
    
    - useNetworkProcesses: clear loading when the modal closes mid-fetch (was 
stuck true)
    - TopologyFocusPicker / TopologyNodeFilter: Escape now closes the dropdown
    - Logs: reset level + tag filters on service switch (cascade-clear)
    - Browser Errors: reset the category filter on service switch 
(cascade-clear)
    - Network create: reset the sampling form after a successful create
    - AlarmsView: drop the empty onMounted hook left by the comment audit
---
 apps/ui/src/layer/browser-errors/LayerBrowserErrorsView.vue | 1 +
 apps/ui/src/layer/logs/LayerLogsView.vue                    | 2 ++
 apps/ui/src/layer/profiling/LayerNetworkProfilingView.vue   | 6 ++++--
 apps/ui/src/layer/profiling/useNetworkProcesses.ts          | 1 +
 apps/ui/src/layer/service-map/TopologyFocusPicker.vue       | 2 ++
 apps/ui/src/layer/service-map/TopologyNodeFilter.vue        | 2 ++
 6 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/apps/ui/src/layer/browser-errors/LayerBrowserErrorsView.vue 
b/apps/ui/src/layer/browser-errors/LayerBrowserErrorsView.vue
index 01867a5..b0ff693 100644
--- a/apps/ui/src/layer/browser-errors/LayerBrowserErrorsView.vue
+++ b/apps/ui/src/layer/browser-errors/LayerBrowserErrorsView.vue
@@ -205,6 +205,7 @@ function catOf(r: BrowserErrorRow): Cat {
 }
 
 const selectedCat = ref<Cat | null>(null);
+watch(serviceName, () => { selectedCat.value = null; });
 function toggleCat(c: Cat): void {
   selectedCat.value = selectedCat.value === c ? null : c;
   // `expanded` indexes into filteredLogs, which just changed — drop it.
diff --git a/apps/ui/src/layer/logs/LayerLogsView.vue 
b/apps/ui/src/layer/logs/LayerLogsView.vue
index 0970e78..2e64e06 100644
--- a/apps/ui/src/layer/logs/LayerLogsView.vue
+++ b/apps/ui/src/layer/logs/LayerLogsView.vue
@@ -234,6 +234,8 @@ function applyConditions(): void {
 // new one). Filter edits just stage; they wait for Run query.
 watch(serviceName, () => {
   hasQueried.value = false;
+  selectedLevel.value = null;
+  customTags.value = [];
   applyConditions();
 });
 const aService = computed(() => applied.value.service);
diff --git a/apps/ui/src/layer/profiling/LayerNetworkProfilingView.vue 
b/apps/ui/src/layer/profiling/LayerNetworkProfilingView.vue
index 3abb64d..91bae2e 100644
--- a/apps/ui/src/layer/profiling/LayerNetworkProfilingView.vue
+++ b/apps/ui/src/layer/profiling/LayerNetworkProfilingView.vue
@@ -286,9 +286,10 @@ const DEFAULT_SETTINGS = (): 
NetworkProfilingSampling['settings'] => ({
   requireCompleteRequest: true,
   requireCompleteResponse: true,
 });
-const samplings = ref<NetworkProfilingSampling[]>([
+const DEFAULT_SAMPLINGS = (): NetworkProfilingSampling[] => [
   { uriRegex: '', minDuration: 0, when4xx: true, when5xx: true, settings: 
DEFAULT_SETTINGS() },
-]);
+];
+const samplings = ref<NetworkProfilingSampling[]>(DEFAULT_SAMPLINGS());
 function addSampling(): void {
   samplings.value.push({ minDuration: 0, when4xx: false, when5xx: false, 
settings: DEFAULT_SETTINGS() });
 }
@@ -316,6 +317,7 @@ async function submitNewTask(): Promise<void> {
       return;
     }
     showNewTask.value = false;
+    samplings.value = DEFAULT_SAMPLINGS();
     await refreshTasks();
     await pollForNewTask({
       idsBefore,
diff --git a/apps/ui/src/layer/profiling/useNetworkProcesses.ts 
b/apps/ui/src/layer/profiling/useNetworkProcesses.ts
index 94713a7..2bc672d 100644
--- a/apps/ui/src/layer/profiling/useNetworkProcesses.ts
+++ b/apps/ui/src/layer/profiling/useNetworkProcesses.ts
@@ -30,6 +30,7 @@ export function useNetworkProcesses(instanceId: Ref<string | 
null>, enabled: Ref
   watch([enabled, instanceId], async ([on, id]) => {
     if (!on || !id) {
       processes.value = [];
+      loading.value = false;
       return;
     }
     loading.value = true;
diff --git a/apps/ui/src/layer/service-map/TopologyFocusPicker.vue 
b/apps/ui/src/layer/service-map/TopologyFocusPicker.vue
index e1a5cb7..74d6940 100644
--- a/apps/ui/src/layer/service-map/TopologyFocusPicker.vue
+++ b/apps/ui/src/layer/service-map/TopologyFocusPicker.vue
@@ -24,6 +24,7 @@
 -->
 <script setup lang="ts">
 import { computed, ref } from 'vue';
+import { useEscapeToClose } from '@/components/primitives/useEscapeToClose';
 import {
   resolveServiceIdentity,
   type ServiceIdentity,
@@ -40,6 +41,7 @@ const emit = defineEmits<{ 'update:selected': [string[]] }>();
 
 const open = ref(false);
 const search = ref('');
+useEscapeToClose(() => open.value, () => { open.value = false; });
 function toggleOpen(): void { open.value = !open.value; }
 function identity(name: string | null | undefined): ServiceIdentity {
   return resolveServiceIdentity(name, props.namingRule);
diff --git a/apps/ui/src/layer/service-map/TopologyNodeFilter.vue 
b/apps/ui/src/layer/service-map/TopologyNodeFilter.vue
index d0ec004..4e355ed 100644
--- a/apps/ui/src/layer/service-map/TopologyNodeFilter.vue
+++ b/apps/ui/src/layer/service-map/TopologyNodeFilter.vue
@@ -26,6 +26,7 @@
 -->
 <script setup lang="ts">
 import { computed, ref } from 'vue';
+import { useEscapeToClose } from '@/components/primitives/useEscapeToClose';
 import type { LayerDef, TopologyNode } from '@/api/client';
 import { isUserNode } from '@/layer/service-map/useTopologyIcons';
 import Icon from '@/components/icons/Icon.vue';
@@ -45,6 +46,7 @@ const emit = defineEmits<{
 
 const OTHERS_TOKEN = 'UNDEFINED'; // OAP's no-layer fallback, shown as "Others"
 const filterOpen = ref(false);
+useEscapeToClose(() => filterOpen.value, () => { filterOpen.value = false; });
 
 function layerTokens(n: TopologyNode): string[] {
   const ls = (n.layers ?? []).filter((l) => l && l.length > 0);

Reply via email to