refactor(web): simplify sidebar visual design

- Remove vertical guide lines from collapsible sub-items (border-l)
- Move create button from list bottom to category header row as a hover-revealed + icon
- Remove active background highlight from category headers; only child entities show active state
- Remove unused CREATE_I18N_KEYS constant
This commit is contained in:
Junyan Qin
2026-03-27 15:00:17 +08:00
parent bc3199bf29
commit cad259fe39
2 changed files with 26 additions and 41 deletions
@@ -130,13 +130,6 @@ const COLLAPSIBLE_ONLY_CATEGORIES: EntityCategoryId[] = [
'knowledge', 'knowledge',
]; ];
// Map creatable category IDs to their i18n "create" keys
const CREATE_I18N_KEYS: Partial<Record<EntityCategoryId, string>> = {
bots: 'bots.createBot',
pipelines: 'pipelines.createPipeline',
knowledge: 'knowledge.createKnowledgeBase',
};
function isEntityCategory(id: string): id is EntityCategoryId { function isEntityCategory(id: string): id is EntityCategoryId {
return (ENTITY_CATEGORY_IDS as readonly string[]).includes(id); return (ENTITY_CATEGORY_IDS as readonly string[]).includes(id);
} }
@@ -336,7 +329,7 @@ function NavItems({
> >
<SidebarMenuItem> <SidebarMenuItem>
<SidebarMenuButton <SidebarMenuButton
isActive={isActive} isActive={false}
onClick={() => { onClick={() => {
if (isCollapseOnly) { if (isCollapseOnly) {
onSectionToggle(config.id, !isOpen); onSectionToggle(config.id, !isOpen);
@@ -345,18 +338,33 @@ function NavItems({
} }
}} }}
tooltip={config.name} tooltip={config.name}
className="group/category-header"
> >
{config.icon} {config.icon}
<span>{config.name}</span> <span>{config.name}</span>
<CollapsibleTrigger asChild> <div className="ml-auto flex items-center gap-0.5 -mr-1">
<button {canCreate && (
type="button" <button
className="ml-auto p-1 -mr-1 rounded-sm hover:bg-sidebar-accent" type="button"
onClick={(e) => e.stopPropagation()} className="p-1 rounded-sm hover:bg-sidebar-accent opacity-0 group-hover/category-header:opacity-100 transition-opacity"
> onClick={(e) => {
<ChevronRight className="size-4 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" /> e.stopPropagation();
</button> router.push(`${routePrefix}?id=new`);
</CollapsibleTrigger> }}
>
<Plus className="size-3.5" />
</button>
)}
<CollapsibleTrigger asChild>
<button
type="button"
className="p-1 rounded-sm hover:bg-sidebar-accent"
onClick={(e) => e.stopPropagation()}
>
<ChevronRight className="size-4 transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</button>
</CollapsibleTrigger>
</div>
</SidebarMenuButton> </SidebarMenuButton>
<CollapsibleContent> <CollapsibleContent>
<SidebarMenuSub> <SidebarMenuSub>
@@ -469,29 +477,6 @@ function NavItems({
</> </>
); );
})()} })()}
{/* Create new entity entry (only for creatable categories) */}
{canCreate && (
<SidebarMenuSubItem>
<SidebarMenuSubButton
asChild
isActive={
pathname === routePrefix &&
searchParams.get('id') === 'new'
}
>
<a
href={`${routePrefix}?id=new`}
onClick={(e) => {
e.preventDefault();
router.push(`${routePrefix}?id=new`);
}}
>
<Plus className="size-4" />
<span>{t(CREATE_I18N_KEYS[config.id] ?? '')}</span>
</a>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
)}
</SidebarMenuSub> </SidebarMenuSub>
</CollapsibleContent> </CollapsibleContent>
</SidebarMenuItem> </SidebarMenuItem>
+1 -1
View File
@@ -651,7 +651,7 @@ function SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {
data-slot="sidebar-menu-sub" data-slot="sidebar-menu-sub"
data-sidebar="menu-sub" data-sidebar="menu-sub"
className={cn( className={cn(
'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5', 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 px-2.5 py-0.5',
'group-data-[collapsible=icon]:hidden', 'group-data-[collapsible=icon]:hidden',
className, className,
)} )}