Merge branch 'fix/sidebar-admin-nav-internal-only' into 'main'
fix(sidebar): hide outbox/audit/webhooks для PUBLIC users See merge request 2-6/2-6-4/terravault/ordinis!221
This commit is contained in:
@@ -63,6 +63,13 @@ type NavItem = {
|
|||||||
* (или {@code ordinis:admin} super-role). Hide если нет.
|
* (или {@code ordinis:admin} super-role). Hide если нет.
|
||||||
*/
|
*/
|
||||||
reviewerOnly?: boolean
|
reviewerOnly?: boolean
|
||||||
|
/**
|
||||||
|
* Admin-only nav entries (outbox/audit/webhooks). Backend возвращает 403
|
||||||
|
* audit_internal_required / outbox_internal_required для PUBLIC-scope users.
|
||||||
|
* Frontend hide'ит вместо показа links → 403 toast (confusing UX).
|
||||||
|
* Hide когда {@link useHasInternalScope} returns false.
|
||||||
|
*/
|
||||||
|
internalOnly?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Sidebar() {
|
export function Sidebar() {
|
||||||
@@ -138,6 +145,7 @@ export function Sidebar() {
|
|||||||
icon: Inbox,
|
icon: Inbox,
|
||||||
badge: outboxPending > 0 ? outboxPending : undefined,
|
badge: outboxPending > 0 ? outboxPending : undefined,
|
||||||
authRequired: true,
|
authRequired: true,
|
||||||
|
internalOnly: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/webhooks',
|
to: '/webhooks',
|
||||||
@@ -145,8 +153,13 @@ export function Sidebar() {
|
|||||||
icon: Webhook,
|
icon: Webhook,
|
||||||
badge: webhooksActive > 0 ? webhooksActive : undefined,
|
badge: webhooksActive > 0 ? webhooksActive : undefined,
|
||||||
authRequired: true,
|
authRequired: true,
|
||||||
|
internalOnly: true,
|
||||||
},
|
},
|
||||||
{ to: '/audit', label: t('nav.audit'), icon: ScrollText, authRequired: true },
|
// /audit, /outbox, /webhooks — admin observability tools. Backend
|
||||||
|
// возвращает 403 (audit_internal_required / outbox_internal_required)
|
||||||
|
// для PUBLIC-scope users. UI больше не показывает links — раньше
|
||||||
|
// PUBLIC users видели nav entries и кликали → 403 toast (confusing).
|
||||||
|
{ to: '/audit', label: t('nav.audit'), icon: ScrollText, authRequired: true, internalOnly: true },
|
||||||
{ to: '/search', label: t('nav.search'), icon: Search },
|
{ to: '/search', label: t('nav.search'), icon: Search },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -158,6 +171,7 @@ export function Sidebar() {
|
|||||||
items: s.items.filter((i) => {
|
items: s.items.filter((i) => {
|
||||||
if (i.authRequired && !canMutate) return false
|
if (i.authRequired && !canMutate) return false
|
||||||
if (i.reviewerOnly && !isReviewer) return false
|
if (i.reviewerOnly && !isReviewer) return false
|
||||||
|
if (i.internalOnly && !hasInternal) return false
|
||||||
return true
|
return true
|
||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
@@ -502,6 +516,7 @@ export function MobileSidebar({ open, onClose }: { open: boolean; onClose: () =>
|
|||||||
icon: Inbox,
|
icon: Inbox,
|
||||||
badge: outboxPending > 0 ? outboxPending : undefined,
|
badge: outboxPending > 0 ? outboxPending : undefined,
|
||||||
authRequired: true,
|
authRequired: true,
|
||||||
|
internalOnly: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/webhooks',
|
to: '/webhooks',
|
||||||
@@ -509,8 +524,9 @@ export function MobileSidebar({ open, onClose }: { open: boolean; onClose: () =>
|
|||||||
icon: Webhook,
|
icon: Webhook,
|
||||||
badge: webhooksActive > 0 ? webhooksActive : undefined,
|
badge: webhooksActive > 0 ? webhooksActive : undefined,
|
||||||
authRequired: true,
|
authRequired: true,
|
||||||
|
internalOnly: true,
|
||||||
},
|
},
|
||||||
{ to: '/audit', label: t('nav.audit'), icon: ScrollText, authRequired: true },
|
{ to: '/audit', label: t('nav.audit'), icon: ScrollText, authRequired: true, internalOnly: true },
|
||||||
{ to: '/search', label: t('nav.search'), icon: Search },
|
{ to: '/search', label: t('nav.search'), icon: Search },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -521,6 +537,7 @@ export function MobileSidebar({ open, onClose }: { open: boolean; onClose: () =>
|
|||||||
items: s.items.filter((i) => {
|
items: s.items.filter((i) => {
|
||||||
if (i.authRequired && !canMutate) return false
|
if (i.authRequired && !canMutate) return false
|
||||||
if (i.reviewerOnly && !isReviewer) return false
|
if (i.reviewerOnly && !isReviewer) return false
|
||||||
|
if (i.internalOnly && !hasInternal) return false
|
||||||
return true
|
return true
|
||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user