118 lines
4.0 KiB
Vue
118 lines
4.0 KiB
Vue
<template>
|
|
<div class="has-text-black">
|
|
<div>{{ row.username }} / {{ row.fullname }} {{$lang('access-right')}}:</div>
|
|
<div class="mt-2">
|
|
<span class="icon-text mr-6" v-for="v in options">
|
|
<a @click="changeOption(v)">
|
|
<SvgIcon v-bind="{name: option===v.code? 'radio-checked.svg' : 'radio-unchecked.svg', type: option===v.code? 'blue' : 'gray', size: 25}" />
|
|
</a>
|
|
<b class="fs-18">{{v[$store.lang==='en'? 'en' : 'name']}}</b>
|
|
</span>
|
|
</div>
|
|
<aside class="menu">
|
|
<ul class="menu-list" v-for="v in topmenu">
|
|
<li>
|
|
<div class="field is-grouped has-background-light has-text-black py-2 px-3">
|
|
<div class="control is-expanded"><b>{{ v[$store.lang] }}</b></div>
|
|
<div class="control" v-if="v.submenu.length===0 && option==='limit'">
|
|
<span class="ml-6 is-clickable" @click="changeTick(v)">
|
|
<SvgIcon v-bind="{name: v.checked? 'checked.svg' : 'uncheck.svg', type: v.checked? 'blue' : 'gray', size: 25}"></SvgIcon>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<ul>
|
|
<li class="border-bottom" v-for="x in v.submenu">
|
|
<div class="field is-grouped py-1">
|
|
<div class="control is-expanded">
|
|
<span class="icon-text">
|
|
<span>{{ x[$store.lang] }}</span>
|
|
</span>
|
|
</div>
|
|
<div class="control" v-if="option==='limit'">
|
|
<span class="ml-6 is-clickable" @click="changeTick(x, v)">
|
|
<SvgIcon v-bind="{name: x.checked? 'checked.svg' : 'uncheck.svg', type: x.checked? 'blue' : 'gray', size: 25}"></SvgIcon>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</aside>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
const { $copy, $getdata, $filter, $find, $insertapi, $deleteapi } = useNuxtApp()
|
|
const props = defineProps({
|
|
row: Object,
|
|
api: String,
|
|
setting: String
|
|
})
|
|
const options = [{code: 'all', name: 'Tất cả tính năng', en: 'All functions'}, {code: 'limit', name: 'Bị giới hạn', en: 'Limited functions'}]
|
|
var option = ref('limit')
|
|
const rows = await $getdata(props.setting, {category__in: ['topmenu', 'submenu']})
|
|
var topmenu = ref([])
|
|
var loanRights = []
|
|
async function getRights(first) {
|
|
loanRights = await $getdata(props.api, {user: props.row.id})
|
|
if(loanRights.length==0 && first) option.value = 'all'
|
|
var rights = $filter(rows, {category: 'topmenu'})
|
|
rights.map(v=>{
|
|
let arr = $filter(rows, {category: 'submenu', classify: v.code})
|
|
arr.map(x=>{
|
|
let found = $find(loanRights, {setting: x.id})
|
|
if(found) {
|
|
x.rightId = found.id
|
|
x.checked = true
|
|
}
|
|
})
|
|
let found = $find(loanRights, {setting: v.id})
|
|
if(found) v.rightId = found.id
|
|
if(arr.length===0) {
|
|
v.checked = found? true : false
|
|
} else v.checked = true
|
|
v.submenu = arr
|
|
})
|
|
topmenu.value = rights
|
|
}
|
|
async function changeTick(x, v) {
|
|
if(x.checked) {
|
|
if(x.rightId) {
|
|
await $deleteapi(props.api, x.rightId)
|
|
x.rightId = null
|
|
}
|
|
x.checked = false
|
|
if(v? v.rightId>0 : false) {
|
|
let idx = v.submenu.findIndex(h=>h.checked)
|
|
if(idx<0) {
|
|
await $deleteapi(props.api, v.rightId)
|
|
v.checked = false
|
|
}
|
|
}
|
|
} else {
|
|
let obj = await $insertapi(props.api, {setting: x.id, user: props.row.id}, undefined, false)
|
|
if(obj) {
|
|
x.checked = true
|
|
x.rightId = obj.id
|
|
}
|
|
x.checked = true
|
|
if(v? !v.rightId : false) {
|
|
let obj = await $insertapi(props.api, {setting: v.id, user: props.row.id}, undefined, false)
|
|
if(obj) {
|
|
v.rightId = obj.rightId
|
|
v.checked = true
|
|
}
|
|
}
|
|
}
|
|
topmenu.value = $copy(topmenu.value)
|
|
}
|
|
async function changeOption(v) {
|
|
option.value = v.code
|
|
if(v.code==='all') {
|
|
if(loanRights.length>0) await $deleteapi(props.api, loanRights)
|
|
} else {
|
|
await getRights()
|
|
}
|
|
}
|
|
await getRights(true)
|
|
</script> |