show-run-errors-and-reprocess #2

Merged
iqbal merged 4 commits from show-run-errors-and-reprocess into main 2026-10-28 09:40:06 +00:00
3 changed files with 29 additions and 12 deletions
Showing only changes of commit d018c6826f - Show all commits

View File

@@ -135,6 +135,9 @@ export function AppLayout() {
const { signOut } = useClerk() const { signOut } = useClerk()
const { pathname } = useLocation() const { pathname } = useLocation()
const current = NAV.find(n => pathname.startsWith(n.to)) const current = NAV.find(n => pathname.startsWith(n.to))
// Nav groups stay closed unless they hold the current page; a click on the label overrides that until the next route.
const [toggled, setToggled] = useState<Partial<Record<Key, boolean>>>({})
useEffect(() => setToggled({}), [pathname])
const name = user?.fullName || user?.primaryEmailAddress?.emailAddress || '-' const name = user?.fullName || user?.primaryEmailAddress?.emailAddress || '-'
return ( return (
@@ -143,14 +146,22 @@ export function AppLayout() {
<NavLink to="/production"><Brand /></NavLink> <NavLink to="/production"><Brand /></NavLink>
<OrgSwitcher /> <OrgSwitcher />
<nav aria-label={t('layout.mainNav')}> <nav aria-label={t('layout.mainNav')}>
{NAV_GROUPS.map(g => [ {NAV_GROUPS.map(g => {
<div key={g.label} className="nav-label">{t(g.label)}</div>, const open = toggled[g.label] ?? g.items.some(n => pathname.startsWith(n.to))
...g.items.map(n => ( return [
<button key={g.label} type="button" className="nav-label" aria-expanded={open} aria-controls={`nav-${g.label}`}
onClick={() => setToggled(s => ({ ...s, [g.label]: !open }))}>
{t(g.label)}<Icon name="chevron-down" />
</button>,
<div key={`${g.label}-items`} id={`nav-${g.label}`} className={open ? 'nav-items' : 'nav-items closed'}>
{g.items.map(n => (
<NavLink key={n.to} to={n.to} className={({ isActive }) => (isActive ? 'active' : undefined)}> <NavLink key={n.to} to={n.to} className={({ isActive }) => (isActive ? 'active' : undefined)}>
<Icon name={n.icon} />{t(n.label)} <Icon name={n.icon} />{t(n.label)}
</NavLink> </NavLink>
)), ))}
])} </div>,
]
})}
</nav> </nav>
<div className="sidebar-help"> <div className="sidebar-help">
<Icon name="info" /> <Icon name="info" />

View File

@@ -17,6 +17,7 @@ const paths: Record<string, string> = {
search: '<circle cx="10" cy="10" r="6"/><path d="m15 15 5 5"/>', search: '<circle cx="10" cy="10" r="6"/><path d="m15 15 5 5"/>',
info: '<circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 7v.2"/>', info: '<circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 7v.2"/>',
check: '<path d="m5 12 4 4L19 6"/>', check: '<path d="m5 12 4 4L19 6"/>',
'chevron-down': '<path d="m6 9 6 6 6-6"/>',
'chevron-updown': '<path d="m8 9 4-4 4 4M8 15l4 4 4-4"/>', 'chevron-updown': '<path d="m8 9 4-4 4 4M8 15l4 4 4-4"/>',
logout:'<path d="M10 4H4v16h6M10 12h11m-4-4 4 4-4 4"/>', logout:'<path d="M10 4H4v16h6M10 12h11m-4-4 4 4-4 4"/>',
plus: '<path d="M12 4v16M4 12h16"/>', plus: '<path d="M12 4v16M4 12h16"/>',

View File

@@ -287,10 +287,15 @@ dialog::backdrop{background:rgba(16,24,40,.45);backdrop-filter:blur(4px)}
@keyframes page-in{from{opacity:0;transform:translateY(6px)}} @keyframes page-in{from{opacity:0;transform:translateY(6px)}}
@media (prefers-reduced-motion:reduce){.skel,.app main{animation:none}} @media (prefers-reduced-motion:reduce){.skel,.app main{animation:none}}
/* Sidebar groups: Dashboard, then Settings */ /* Sidebar groups: Dashboard, then Settings, each a dropdown that opens on its active page */
.sidebar nav .nav-label{margin:0 12px 6px} .sidebar nav button.nav-label{display:flex;align-items:center;justify-content:space-between;width:auto;margin:0 0 2px;padding:6px 12px;border-radius:8px;color:var(--muted);font-size:11px;font-weight:600;box-shadow:none;background:none}
.sidebar nav .nav-label~.nav-label{margin-top:18px} .sidebar nav button.nav-label:hover{background:#f2f7ff;color:var(--ink)}
@media(max-width:700px){.sidebar nav .nav-label{display:none}} .sidebar nav button.nav-label svg{width:14px;height:14px;color:inherit;transition:transform .15s}
.sidebar nav button.nav-label[aria-expanded=false] svg{transform:rotate(-90deg)}
.sidebar nav .nav-items~.nav-label{margin-top:12px}
.nav-items{display:contents}
@media(min-width:701px){.nav-items.closed{display:none}}
@media(max-width:700px){.sidebar nav button.nav-label{display:none}}
/* Production: the knowledge graph, then the metric row and the latest content */ /* Production: the knowledge graph, then the metric row and the latest content */
.prod-metrics{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:24px} .prod-metrics{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:24px}