refactor(nav): reorganize sidebar with dynamic sections at top
- move runs and sessions to top of navigation (most dynamic) - add visual separator between dynamic and configuration sections - reorder remaining items: scenarios, snippets, credentials, environments - implement separator component in nav rendering logic
This commit is contained in:
@@ -95,6 +95,12 @@
|
||||
background: var(--color-secondary-hover);
|
||||
}
|
||||
|
||||
.navSeparator {
|
||||
height: var(--border-width);
|
||||
background: var(--color-border);
|
||||
margin: var(--space-2) var(--space-2);
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
+20
-12
@@ -90,13 +90,17 @@ const SnippetDetailPage = lazy(() =>
|
||||
import('./pages/snippet/SnippetDetailPage').then((m) => ({ default: m.SnippetDetailPage })),
|
||||
);
|
||||
|
||||
const NAV: { path: string; labelKey: string; Icon: LucideIcon }[] = [
|
||||
{ path: '/environments', labelKey: 'nav.environments', Icon: Globe },
|
||||
{ path: '/credentials', labelKey: 'nav.credentials', Icon: KeyRound },
|
||||
{ path: '/snippets', labelKey: 'nav.snippets', Icon: Braces },
|
||||
{ path: '/sessions', labelKey: 'nav.sessions', Icon: Monitor },
|
||||
{ path: '/scenarios', labelKey: 'nav.scenarios', Icon: ClipboardList },
|
||||
const NAV: (
|
||||
| { path: string; labelKey: string; Icon: LucideIcon }
|
||||
| { separator: true }
|
||||
)[] = [
|
||||
{ path: '/runs', labelKey: 'nav.runs', Icon: Activity },
|
||||
{ path: '/sessions', labelKey: 'nav.sessions', Icon: Monitor },
|
||||
{ separator: true },
|
||||
{ path: '/scenarios', labelKey: 'nav.scenarios', Icon: ClipboardList },
|
||||
{ path: '/snippets', labelKey: 'nav.snippets', Icon: Braces },
|
||||
{ path: '/credentials', labelKey: 'nav.credentials', Icon: KeyRound },
|
||||
{ path: '/environments', labelKey: 'nav.environments', Icon: Globe },
|
||||
];
|
||||
|
||||
export default function App() {
|
||||
@@ -114,18 +118,22 @@ export default function App() {
|
||||
>
|
||||
<div className={styles.sideContent}>
|
||||
<nav className={styles.nav}>
|
||||
{NAV.map(({ path, labelKey, Icon }) => (
|
||||
{NAV.map((item, index) =>
|
||||
'separator' in item ? (
|
||||
<div key={`separator-${index}`} className={styles.navSeparator} />
|
||||
) : (
|
||||
<NavLink
|
||||
key={path}
|
||||
to={path}
|
||||
key={item.path}
|
||||
to={item.path}
|
||||
className={({ isActive }) =>
|
||||
[styles.navItem, isActive ? styles.navItemActive : ''].filter(Boolean).join(' ')
|
||||
}
|
||||
>
|
||||
<Icon size={16} className={styles.navIcon} aria-hidden="true" />
|
||||
{t(labelKey)}
|
||||
<item.Icon size={16} className={styles.navIcon} aria-hidden="true" />
|
||||
{t(item.labelKey)}
|
||||
</NavLink>
|
||||
))}
|
||||
),
|
||||
)}
|
||||
</nav>
|
||||
|
||||
<div className={styles.sideFooter}>
|
||||
|
||||
Reference in New Issue
Block a user