From 5a91af632143f1f72385e5085c5328f2b13b9f14 Mon Sep 17 00:00:00 2001 From: fxai Date: Thu, 29 Oct 2026 08:57:35 +0100 Subject: [PATCH] feat(frontend): implement tabs in asset selection modal --- .../assessment/ActivityAssetsManager.vue | 55 +++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/assessment/ActivityAssetsManager.vue b/frontend/src/components/assessment/ActivityAssetsManager.vue index aaa6272..032dfb9 100644 --- a/frontend/src/components/assessment/ActivityAssetsManager.vue +++ b/frontend/src/components/assessment/ActivityAssetsManager.vue @@ -129,6 +129,35 @@ function accentFor(key: string): string { return props.accentColor ?? DEFAULT_SECTION_ACCENT[key] ?? 'green'; } +// Browser-style dialog tabs (same look as the activity form section tabs): coloured dot + top border per accent +const ACCENT_TAB_CLASS: Record = { + green: { + dot: 'bg-green-500', + accent: 'hover:border-t-green-500/50 data-[state=active]:border-t-green-500 dark:data-[state=active]:border-t-green-500', + }, + orange: { + dot: 'bg-orange-500', + accent: 'hover:border-t-orange-500/50 data-[state=active]:border-t-orange-500 dark:data-[state=active]:border-t-orange-500', + }, + purple: { + dot: 'bg-purple-500', + accent: 'hover:border-t-purple-500/50 data-[state=active]:border-t-purple-500 dark:data-[state=active]:border-t-purple-500', + }, + blue: { + dot: 'bg-blue-700', + accent: 'hover:border-t-blue-700/50 data-[state=active]:border-t-blue-700 dark:data-[state=active]:border-t-blue-700', + }, +}; +const DIALOG_TAB_CLASS = [ + '-mb-px h-11 min-w-[160px] flex-none justify-start gap-2.5 px-5 text-base capitalize', + // Inactive tabs look like background browser tabs: light fill, border open at the bottom + 'rounded-t-lg rounded-b-none border border-t-2 border-border/60 border-b-transparent', + 'cursor-pointer bg-muted/40 text-muted-foreground dark:text-muted-foreground transition-colors hover:bg-muted hover:text-foreground', + // The active tab covers the panel's top border so it joins the panel below + 'data-[state=active]:relative data-[state=active]:z-10 data-[state=active]:border-border data-[state=active]:border-b-card data-[state=active]:bg-card data-[state=active]:text-foreground data-[state=active]:shadow-none', + 'dark:data-[state=active]:border-border dark:data-[state=active]:border-b-card dark:data-[state=active]:bg-card', +].join(' '); + // Add / empty-state tiles use the same footprint as an asset tile const placeholderTileClass = computed(() => [ 'flex items-center justify-center gap-1.5 text-center text-muted-foreground', @@ -454,18 +483,32 @@ onMounted(() => { Manage Assets + +
- - + + + {{ tab }} + {{ getListForTab(tab).length }} -
Select {{ sourcesLabel || 'sources' }}
+
Select {{ sourcesLabel || 'sources' }}
+ +
-
+
{
-
+
No assets found. @@ -505,6 +548,8 @@ onMounted(() => {
+
+