Problem
The admin page (/admin) has hardcoded tabs (Users, Organizations). Downstream projects need to add their own admin tabs (e.g. Costs, Logs, Billing) but currently have to either:
- Fork
admin.view.vue and hardcode new tabs
- Create separate sidenav items (bad UX — splits admin into multiple nav entries)
Proposed solution
Add an adminTabs array to the admin module config (or the app-level config) that downstream projects can extend:
```js
// config/index.js (downstream project)
admin: {
tabs: [
{ value: 'costs', label: 'Costs', icon: 'fa-solid fa-coins', route: '/admin/costs' },
],
}
```
admin.view.vue reads this config and renders extra tabs alongside the default Users/Organizations tabs.
Expected behavior
- Default tabs (Users, Organizations) always rendered
- Extra tabs from config rendered after defaults
- Each extra tab is a
<router-link> / <v-tab :to="tab.route"> pointing to the downstream route
- Tab hidden if user doesn't have
manage UserAdmin ability (same guard as today)
- No change to existing downstream projects that don't use this config
Acceptance criteria
Context
First downstream use case: trawl_vue needs a "Costs" tab → /admin/costs (cost tracking per history — D5.5).
Problem
The admin page (
/admin) has hardcoded tabs (Users, Organizations). Downstream projects need to add their own admin tabs (e.g. Costs, Logs, Billing) but currently have to either:admin.view.vueand hardcode new tabsProposed solution
Add an
adminTabsarray to the admin module config (or the app-level config) that downstream projects can extend:```js
// config/index.js (downstream project)
admin: {
tabs: [
{ value: 'costs', label: 'Costs', icon: 'fa-solid fa-coins', route: '/admin/costs' },
],
}
```
admin.view.vuereads this config and renders extra tabs alongside the default Users/Organizations tabs.Expected behavior
<router-link>/<v-tab :to="tab.route">pointing to the downstream routemanage UserAdminability (same guard as today)Acceptance criteria
config.admin.tabsarray read inadmin.view.vue{ value, label, icon, route }—iconoptionalv-tabwith<router-link>(ortoprop)Context
First downstream use case:
trawl_vueneeds a "Costs" tab →/admin/costs(cost tracking per history — D5.5).