chore(layout): remove v2 nav-folding orphans surfaced by P4 refactor
P4 (Plan 2.5, AD-2.5-W1 + AD-2.5-B1) refactored SidebarNav to read APP_NAVIGATION directly, retiring the OrganizerLayoutV2 → useV2Nav → AppSidebar :groups → SidebarNav :groups props chain. Five artifacts were deliberately left in place to keep the P4 diff focused — this commit removes them. Deleted: - src/composables/useV2Nav.ts (+ spec) — v1→v2 nav fold adapter, no production consumer post-P4 - src/types/v2/nav.ts — V2NavGroup / V2NavItem types, only consumed by the deleted composables above. types/v2/ directory removed (empty) - src/components-v2/layout/sidebarNavActive.ts (+ spec) — pure helper, SidebarNav now uses inlined active check against NavItem.routeName - navFixture export + V2NavGroup import from stories/v2/_helpers.ts Also: stale "useV2Nav(orgNavItems)" reference scrubbed from OrganizerLayoutV2.vue docstring (the function no longer exists; the comment now describes the retired plumbing generically). Suite delta: 575 → 557 (−18 specs). The drop is correct — the removed specs tested deleted dead code (sidebarNavActive: 8 specs, useV2Nav: 10 specs), not contract behaviour. vue-tsc clean. Scoped ESLint clean (0 errors). Final re-grep on all deleted symbols (useV2Nav, V2NavGroup, V2NavItem, sidebarNavActive, navFixture) returns zero hits across apps/app/src/. Per zero-compromise gap 5 (delete > adapt): orphans don't stay. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { isNavItemActive } from '@/components-v2/layout/sidebarNavActive'
|
||||
import type { V2NavItem } from '@/types/v2/nav'
|
||||
|
||||
function makeItem(name: string): V2NavItem {
|
||||
return { id: name, label: name, icon: 'tabler-home', to: { name } }
|
||||
}
|
||||
|
||||
describe('isNavItemActive', () => {
|
||||
it('returns true when the current route name exactly matches', () => {
|
||||
expect(isNavItemActive(makeItem('dashboard'), 'dashboard')).toBe(true)
|
||||
})
|
||||
|
||||
it('returns false when the current route name differs', () => {
|
||||
expect(isNavItemActive(makeItem('dashboard'), 'events')).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false when currentRouteName is null', () => {
|
||||
expect(isNavItemActive(makeItem('dashboard'), null)).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false when currentRouteName is undefined', () => {
|
||||
expect(isNavItemActive(makeItem('dashboard'), undefined)).toBe(false)
|
||||
})
|
||||
|
||||
it('returns true for nested routes: item name is a prefix of current route (dash-separated)', () => {
|
||||
// e.g. item "organisation" should be active on route "organisation-settings"
|
||||
expect(isNavItemActive(makeItem('organisation'), 'organisation-settings')).toBe(true)
|
||||
})
|
||||
|
||||
it('does not match partial-word prefixes: "org" should NOT match "organisation-settings"', () => {
|
||||
expect(isNavItemActive(makeItem('org'), 'organisation-settings')).toBe(false)
|
||||
})
|
||||
|
||||
it('handles symbol route names: returns false (not string — no match)', () => {
|
||||
const sym = Symbol('dashboard')
|
||||
|
||||
expect(isNavItemActive(makeItem('dashboard'), sym)).toBe(false)
|
||||
})
|
||||
|
||||
it('item with to as { name: string } matches correctly', () => {
|
||||
const item: V2NavItem = { id: 'events', label: 'Events', icon: 'tabler-calendar', to: { name: 'events' } }
|
||||
|
||||
expect(isNavItemActive(item, 'events')).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -1,37 +0,0 @@
|
||||
import type { V2NavItem } from '@/types/v2/nav'
|
||||
|
||||
/**
|
||||
* Pure helper — determines whether a V2NavItem is "active" given the current
|
||||
* route name.
|
||||
*
|
||||
* Active rules (simplest correct definition):
|
||||
* 1. Exact match: currentRouteName === item.to.name
|
||||
* 2. Prefix match for nested routes: currentRouteName starts with
|
||||
* item.to.name + '-' (e.g. item "organisation" is active on
|
||||
* "organisation-settings"). The dash boundary prevents "org" from
|
||||
* spuriously matching "organisation-settings".
|
||||
*
|
||||
* Only `to` values that are a plain object with a string `name` property are
|
||||
* compared — string/array `to` values always return false (router-push
|
||||
* style not used in v1 nav).
|
||||
*/
|
||||
export function isNavItemActive(
|
||||
item: V2NavItem,
|
||||
currentRouteName: string | symbol | null | undefined,
|
||||
): boolean {
|
||||
if (typeof currentRouteName !== 'string')
|
||||
return false
|
||||
|
||||
const to = item.to
|
||||
|
||||
if (typeof to !== 'object' || to === null || Array.isArray(to))
|
||||
return false
|
||||
|
||||
const itemName = (to as { name?: unknown }).name
|
||||
|
||||
if (typeof itemName !== 'string')
|
||||
return false
|
||||
|
||||
return currentRouteName === itemName
|
||||
|| currentRouteName.startsWith(`${itemName}-`)
|
||||
}
|
||||
Reference in New Issue
Block a user