Skip to content

Commit 7b27dec

Browse files
committed
Rename Discovery to Scans, add active scan indicator
- Rename sidebar label from "Discovery" to "Scans" to avoid redundancy under the "Discover" section header - Show green notification dot on sidebar Scans icon when a discovery session is actively running - Show matching dot on Sessions sub-tab via new notifications prop on ContentSubTabs
1 parent 7a8878a commit 7b27dec

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

ui/src/lib/shared/components/layout/ContentSubTabs.svelte

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
let {
1313
tabs,
1414
activeTab = $bindable(),
15-
isReadOnly = false
15+
isReadOnly = false,
16+
notifications
1617
}: {
1718
tabs: SubTab[];
1819
activeTab: string;
1920
isReadOnly: boolean;
21+
notifications?: Record<string, string>;
2022
} = $props();
2123
</script>
2224

@@ -38,7 +40,15 @@
3840
aria-current={activeTab === tab.id ? 'page' : undefined}
3941
>
4042
<div class="flex items-center gap-2">
41-
<tab.icon class="h-4 w-4" />
43+
<span class="relative">
44+
<tab.icon class="h-4 w-4" />
45+
{#if notifications?.[tab.id]}
46+
<span
47+
class="absolute -right-1 -top-1 h-2 w-2 rounded-full"
48+
style="background-color: {notifications[tab.id]}"
49+
></span>
50+
{/if}
51+
</span>
4252
{tab.label}
4353
</div>
4454
</button>

ui/src/lib/shared/components/layout/Sidebar.svelte

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import SettingsModal from '$lib/features/settings/SettingsModal.svelte';
66
import SupportModal from '$lib/features/support/SupportModal.svelte';
77
import { entities } from '$lib/shared/stores/metadata';
8+
import { useActiveSessionsQuery } from '$lib/features/discovery/queries';
89
import { modalState, openModal } from '$lib/shared/stores/modal-registry';
910
import { entityUIConfig, TAB_LABELS } from '$lib/shared/entity-ui-config';
1011
import type { EntityDiscriminants } from '$lib/api/entities';
@@ -58,6 +59,7 @@
5859
isReadOnly: boolean;
5960
subTabIds?: string[];
6061
subTabDefs?: SubTab[];
62+
subTabNotifications?: Record<string, string>;
6163
}>
6264
>([]),
6365
showSettings = $bindable(false),
@@ -73,6 +75,7 @@
7375
isReadOnly: boolean;
7476
subTabIds?: string[];
7577
subTabDefs?: SubTab[];
78+
subTabNotifications?: Record<string, string>;
7679
}>;
7780
showSettings?: boolean;
7881
settingsInitialTab?: string;
@@ -107,6 +110,10 @@
107110
return isPastDue || (isTrialing && !hasPayment);
108111
});
109112
113+
// Active discovery sessions — used for notification dot on sidebar and sub-tabs
114+
const activeSessionsQuery = useActiveSessionsQuery(() => true);
115+
let hasActiveSessions = $derived((activeSessionsQuery.data?.length ?? 0) > 0);
116+
110117
// Sync settings/support modal state from modal registry (for deep-link opens)
111118
$effect(() => {
112119
if ($modalState.name === 'settings' && !showSettings) {
@@ -331,6 +338,7 @@
331338
isReadOnly: boolean;
332339
subTabIds?: string[];
333340
subTabDefs?: SubTab[];
341+
subTabNotifications?: Record<string, string>;
334342
}> = [];
335343
336344
// Helper to extract tabs from an item and its children
@@ -349,7 +357,11 @@
349357
component: null,
350358
isReadOnly,
351359
subTabIds: visibleSubTabs.map((st) => st.id),
352-
subTabDefs: visibleSubTabs
360+
subTabDefs: visibleSubTabs,
361+
subTabNotifications:
362+
item.id === 'discovery' && hasActiveSessions
363+
? { 'discovery-sessions': entities.getColorHelper('Discovery').rgb }
364+
: undefined
353365
});
354366
}
355367
} else if (item.component) {
@@ -647,7 +659,15 @@
647659
style="height: 2.5rem; padding: 0.5rem 0.75rem;"
648660
title={collapsed ? item.label : ''}
649661
>
650-
<item.icon class="h-5 w-5 flex-shrink-0" />
662+
<span class="relative">
663+
<item.icon class="h-5 w-5 flex-shrink-0" />
664+
{#if item.id === 'discovery' && hasActiveSessions}
665+
<span
666+
class="absolute -right-1 -top-1 h-2.5 w-2.5 rounded-full"
667+
style="background-color: {entities.getColorHelper('Discovery').rgb}"
668+
></span>
669+
{/if}
670+
</span>
651671
{#if !collapsed}
652672
<span class="ml-3 truncate">{item.label}</span>
653673
{/if}

ui/src/lib/shared/entity-ui-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const TAB_LABELS: Record<string, string> = {
3636
topology: 'Topology',
3737
groups: 'Groups',
3838
shares: 'Sharing',
39-
discovery: 'Discovery',
39+
discovery: 'Scans',
4040
'discovery-sessions': 'Sessions',
4141
'discovery-scheduled': 'Scheduled',
4242
'discovery-history': 'History',

ui/src/routes/+page.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
isReadOnly: boolean;
6464
subTabIds?: string[];
6565
subTabDefs?: SubTab[];
66+
subTabNotifications?: Record<string, string>;
6667
}>
6768
>([]);
6869
@@ -165,7 +166,12 @@
165166
{#each allTabs as tab (tab.id)}
166167
{#if tab.subTabIds && tab.subTabDefs}
167168
<div class={!tab.subTabIds.includes(activeTab) ? 'h-0 overflow-hidden' : ''}>
168-
<ContentSubTabs tabs={tab.subTabDefs} bind:activeTab isReadOnly={tab.isReadOnly} />
169+
<ContentSubTabs
170+
tabs={tab.subTabDefs}
171+
bind:activeTab
172+
isReadOnly={tab.isReadOnly}
173+
notifications={tab.subTabNotifications}
174+
/>
169175
</div>
170176
{:else}
171177
<div class={activeTab !== tab.id ? 'h-0 overflow-hidden' : ''}>

0 commit comments

Comments
 (0)