Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .downstream/native-domains.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ nothing. While no Codex runtime row is stored,

## Codex gateway borrowing

The Extensions navigation exposes three administrator pages: settings at
The Extensions sidebar has one Codex Borrowing entry. Its in-page navigation
switches between three independently addressable administrator pages: settings at
`/admin/codex-gateway-borrow`, route status at
`/admin/codex-gateway-borrow/status`, and manual comparison/history at
`/admin/codex-pelican-comparison`. Opening or navigating these pages only reads
Expand Down
19 changes: 8 additions & 11 deletions frontend/src/components/layout/AppSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
:key="item.path"
:to="item.path"
class="sidebar-link mb-1"
:class="{ 'sidebar-link-active': route.path === item.path, 'sidebar-link-collapsed': sidebarCollapsed }"
:class="{ 'sidebar-link-active': isExtensionActive(item.path), 'sidebar-link-collapsed': sidebarCollapsed }"
:title="sidebarCollapsed ? item.label : undefined"
@click="handleMenuItemClick(item.path)"
>
Expand Down Expand Up @@ -507,14 +507,6 @@ const GatewayBorrowIcon = {
render: () => h(Icon, { name: 'link', 'aria-hidden': 'true' })
}

const GatewayBorrowStatusIcon = {
render: () => h(Icon, { name: 'checkCircle', 'aria-hidden': 'true' })
}

const PelicanComparisonIcon = {
render: () => h(Icon, { name: 'grid', 'aria-hidden': 'true' })
}

const BellIcon = {
render: () =>
h(
Expand Down Expand Up @@ -842,8 +834,6 @@ const adminExtensionNavItems = computed((): NavItem[] => [
{ path: '/admin/system-prompts', label: t('nav.systemPrompts'), icon: DocumentIcon },
{ path: '/admin/codex-runtime', label: t('nav.codexRuntime'), icon: PluginIcon },
{ path: '/admin/codex-gateway-borrow', label: t('nav.codexGatewayBorrow'), icon: GatewayBorrowIcon },
{ path: '/admin/codex-gateway-borrow/status', label: t('nav.codexGatewayBorrowStatus'), icon: GatewayBorrowStatusIcon },
{ path: '/admin/codex-pelican-comparison', label: t('nav.codexPelicanComparison'), icon: PelicanComparisonIcon },
{ path: '/admin/reasoning-recovery', label: t('nav.reasoningRecovery'), icon: RecoveryIcon },
])

Expand Down Expand Up @@ -986,6 +976,13 @@ function isActive(path: string): boolean {
return route.path === path || route.path.startsWith(path + '/')
}

function isExtensionActive(path: string): boolean {
if (path === '/admin/codex-gateway-borrow') {
return isActive(path) || route.path === '/admin/codex-pelican-comparison'
}
return route.path === path
}

function isGroupActive(item: NavItem): boolean {
if (!item.children) return false
return item.children.some(child => route.path === child.path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,13 @@ describe('AppSidebar simple mode extensions', () => {
wrapper.unmount()
})

it.each([true, false])('renders the three admin page entries in order (simple: %s)', async simple => {
it.each([true, false])('renders one borrowing entry with page navigation kept inside (simple: %s)', async simple => {
const wrapper = await renderSidebar({ admin: true, simple })

expect(extensionLinks(wrapper)).toEqual([
'/admin/system-prompts',
'/admin/codex-runtime',
'/admin/codex-gateway-borrow',
'/admin/codex-gateway-borrow/status',
'/admin/codex-pelican-comparison',
'/admin/reasoning-recovery',
])
if (simple) expect(wrapper.text()).not.toContain('nav.myAccount')
Expand All @@ -126,12 +124,17 @@ describe('AppSidebar simple mode extensions', () => {
regularUser.unmount()
})

it('marks only Borrow Status active on its own route', async () => {
const wrapper = await renderSidebar({ admin: true, path: '/admin/codex-gateway-borrow/status' })
it.each([
'/admin/codex-gateway-borrow',
'/admin/codex-gateway-borrow/status',
'/admin/codex-pelican-comparison',
])('keeps the single borrowing entry active on %s', async path => {
const wrapper = await renderSidebar({ admin: true, path })
const section = wrapper.get('[data-testid="sidebar-extensions"]')

expect(section.get('a[href="/admin/codex-gateway-borrow/status"]').classes()).toContain('sidebar-link-active')
expect(section.get('a[href="/admin/codex-gateway-borrow"]').classes()).not.toContain('sidebar-link-active')
expect(section.get('a[href="/admin/codex-gateway-borrow"]').classes()).toContain('sidebar-link-active')
expect(section.find('a[href="/admin/codex-gateway-borrow/status"]').exists()).toBe(false)
expect(section.find('a[href="/admin/codex-pelican-comparison"]').exists()).toBe(false)
expect(section.findAll('.sidebar-link-active')).toHaveLength(1)
wrapper.unmount()
})
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/i18n/locales/en/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export default {
auditLogs: 'Audit Logs',
systemPrompts: 'System Prompts',
reasoningRecovery: 'Reasoning Recovery',
codexGatewayBorrow: 'Codex Borrow Settings',
codexGatewayBorrow: 'Codex Borrowing',
codexGatewayBorrowStatus: 'Codex Borrow Status',
codexPelicanComparison: 'Pelican Comparison',
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/i18n/locales/zh/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export default {
auditLogs: '操作日志',
systemPrompts: '系统提示词',
reasoningRecovery: '推理恢复',
codexGatewayBorrow: 'Codex 借用设置',
codexGatewayBorrow: 'Codex 借用',
codexGatewayBorrowStatus: 'Codex 借用状态',
codexPelicanComparison: '鹈鹕对比',
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ const routes: RouteRecordRaw[] = [
path: '/admin/codex-gateway-borrow',
name: 'AdminCodexGatewayBorrow',
component: () => import('@/views/admin/CodexGatewayBorrowView.vue'),
meta: { requiresAuth: true, requiresAdmin: true, title: 'Codex Borrow Settings', titleKey: 'nav.codexGatewayBorrow' }
meta: { requiresAuth: true, requiresAdmin: true, title: 'Codex Borrow Settings', titleKey: 'admin.codexGatewayBorrow.title' }
},
{
path: '/admin/codex-gateway-borrow/status',
Expand Down
Loading