fix: restore Sense permission navigation (#44)
This commit is contained in:
@@ -10,7 +10,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"lint": "eslint \"src/**/*.{js,vue}\""
|
"lint": "eslint \"src/**/*.{js,vue}\"",
|
||||||
|
"test:navigation": "node --test tests/navigation.test.cjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "2.3.2",
|
"@element-plus/icons-vue": "2.3.2",
|
||||||
@@ -50,4 +51,3 @@
|
|||||||
"not dead"
|
"not dead"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,22 +58,14 @@ import { computed, ref } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
|
import { buildNavigation } from './navigation'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const collapsed = ref(false)
|
const collapsed = ref(false)
|
||||||
const navigation = computed(() => {
|
const navigation = computed(() => {
|
||||||
const root = router.getRoutes().find((route) => route.path === '/')
|
|
||||||
const permissions = store.getters['sense-identity/permissions'] || []
|
const permissions = store.getters['sense-identity/permissions'] || []
|
||||||
return (root?.children || [])
|
return buildNavigation(router.getRoutes(), permissions)
|
||||||
.filter((route) => route.meta?.title && !route.meta?.hidden)
|
|
||||||
.filter((route) => !route.meta?.permission || permissions.includes(route.meta.permission))
|
|
||||||
.map((route) => ({
|
|
||||||
path: route.path ? `/${route.path}`.replace('//', '/') : '/',
|
|
||||||
title: route.meta.title,
|
|
||||||
icon: route.meta.icon,
|
|
||||||
order: route.meta.order || 0
|
|
||||||
}))
|
|
||||||
.sort((left, right) => left.order - right.order)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
function buildNavigation(routes, permissions = []) {
|
||||||
|
const layout = routes
|
||||||
|
.filter((route) => route.path === '/' && Array.isArray(route.children) && route.children.length > 0)
|
||||||
|
.sort((left, right) => right.children.length - left.children.length)[0]
|
||||||
|
|
||||||
|
return (layout?.children || [])
|
||||||
|
.filter((route) => route.meta?.title && !route.meta?.hidden)
|
||||||
|
.filter((route) => !route.meta?.permission || permissions.includes(route.meta.permission))
|
||||||
|
.map((route) => ({
|
||||||
|
path: route.path ? `/${route.path}`.replace('//', '/') : '/',
|
||||||
|
title: route.meta.title,
|
||||||
|
icon: route.meta.icon,
|
||||||
|
order: route.meta.order || 0
|
||||||
|
}))
|
||||||
|
.sort((left, right) => left.order - right.order)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { buildNavigation }
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
const assert = require('node:assert/strict')
|
||||||
|
const test = require('node:test')
|
||||||
|
|
||||||
|
const { buildNavigation } = require('../src/layout/navigation.js')
|
||||||
|
|
||||||
|
test('selects the layout record when normalized routes contain duplicate root paths', () => {
|
||||||
|
const routes = [
|
||||||
|
{ path: '/', name: 'sense-dashboard', children: [], meta: { title: '工作台' } },
|
||||||
|
{ path: '/devices', name: 'sense-devices', children: [], meta: { title: '设备管理' } },
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
children: [
|
||||||
|
{ path: 'devices', meta: { title: '设备管理', permission: 'device.read', order: 10 } },
|
||||||
|
{ path: '', meta: { title: '工作台', order: 0 } },
|
||||||
|
{ path: 'users', meta: { title: '用户与权限', permission: 'identity.users.read', order: 90 } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
assert.deepEqual(buildNavigation(routes, ['device.read']), [
|
||||||
|
{ path: '/', title: '工作台', icon: undefined, order: 0 },
|
||||||
|
{ path: '/devices', title: '设备管理', icon: undefined, order: 10 }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns no unauthorized or hidden entries', () => {
|
||||||
|
const routes = [{
|
||||||
|
path: '/',
|
||||||
|
children: [
|
||||||
|
{ path: '', meta: { title: '工作台' } },
|
||||||
|
{ path: 'users', meta: { title: '用户与权限', permission: 'identity.users.read' } },
|
||||||
|
{ path: 'internal', meta: { title: '内部页', hidden: true } }
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
|
||||||
|
assert.deepEqual(buildNavigation(routes), [
|
||||||
|
{ path: '/', title: '工作台', icon: undefined, order: 0 }
|
||||||
|
])
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user