Files
bssapp/ui/src/pages/PermissionMatrix.vue

307 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<q-page v-if="canReadSystem" padding>
<div class="text-h6 q-mb-md">
Rol + Departman Yetkilendirme
</div>
<!-- SELECTS -->
<div class="row q-col-gutter-md q-mb-md">
<div class="col-4">
<q-select
v-model="roleId"
:options="roles"
label="Rol"
dense
outlined
emit-value
map-options
@update:model-value="loadMatrix"
/>
</div>
<div class="col-4">
<q-select
v-model="deptCode"
:options="departments"
label="Departman"
dense
outlined
emit-value
map-options
@update:model-value="loadMatrix"
/>
</div>
</div>
<!-- TABLE -->
<q-table
:rows="rows"
:columns="columns"
row-key="module"
flat
bordered
dense
:loading="loading"
>
<template v-slot:body-cell="props">
<q-td :props="props">
<!-- MODULE NAME -->
<span v-if="props.col.name === 'module'">
{{ props.row.label }}
</span>
<!-- CHECKBOX -->
<q-checkbox
v-else
v-model="props.row[props.col.name]"
dense
@update:model-value="dirty = true"
/>
</q-td>
</template>
</q-table>
<!-- SAVE -->
<div class="q-mt-md">
<q-btn
v-if="canUpdateUser"
color="primary"
icon="save"
label="Kaydet"
:disable="!dirty"
@click="save"
/>
</div>
</q-page>
<q-page v-else class="q-pa-md flex flex-center">
<div class="text-negative text-subtitle1">
Bu module erisim yetkiniz yok.
</div>
</q-page>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { Notify } from 'quasar'
import api from 'src/services/api'
import { usePermission } from 'src/composables/usePermission'
const { canRead, canUpdate } = usePermission()
const canReadSystem = canRead('system')
const canUpdateUser = canUpdate('user')
/* ================= STATE ================= */
const roles = ref([])
const departments = ref([])
const roleId = ref(null)
const deptCode = ref(null)
const rows = ref([])
const loading = ref(false)
const dirty = ref(false)
/* ================= ACTION MAP ================= */
const actions = [
{ key: 'write', label: 'Ekleme' },
{ key: 'read', label: 'Görüntüleme' },
{ key: 'delete', label: 'Silme' },
{ key: 'update', label: 'Güncelleme' },
{ key: 'export', label: ıktı' }
]
/* ================= MODULES ================= */
const [r, d, m] = await Promise.all([
api.get('/lookups/roles'),
api.get('/lookups/departments'),
api.get('/lookups/modules')
])
modules.value = m.data || []
/* ================= TABLE ================= */
const columns = [
{
name: 'module',
label: 'Modül',
field: 'label',
align: 'left'
},
...actions.map(a => ({
name: a.key,
label: a.label,
align: 'center'
}))
]
/* ================= LOAD LOOKUPS ================= */
async function loadLookups () {
const [r, d] = await Promise.all([
api.get('/lookups/roles'),
api.get('/lookups/departments')
])
roles.value = r.data
departments.value = d.data
}
/* ================= INIT TABLE ================= */
function initMatrix () {
rows.value = modules.map(m => {
const row = {
module: m.code,
label: m.label
}
actions.forEach(a => {
row[a.key] = false
})
return row
})
}
/* ================= LOAD ================= */
async function loadMatrix () {
if (!roleId.value || !deptCode.value) return
loading.value = true
try {
initMatrix()
const res = await api.get(
`/roles/${roleId.value}/departments/${deptCode.value}/permissions`
)
list.forEach(p => {
const code = String(p.module_code || p.module)
.toLowerCase()
.trim()
// 🔥 kritik
const row = rows.value.find(r => r.module === code)
if (row) {
row[p.action] = p.allowed
}
})
dirty.value = false
} catch {
Notify.create({
type: 'negative',
message: 'Yetkiler yüklenemedi'
})
} finally {
loading.value = false
}
}
/* ================= SAVE ================= */
async function save () {
try {
loading.value = true
const payload = []
rows.value.forEach(r => {
actions.forEach(a => {
payload.push({
module: r.module,
action: a.key,
allowed: r[a.key]
})
})
})
await api.post(
`/roles/${roleId.value}/departments/${deptCode.value}/permissions`,
payload
)
Notify.create({
type: 'positive',
message: 'Kaydedildi'
})
dirty.value = false
} catch {
Notify.create({
type: 'negative',
message: 'Kayıt hatası'
})
} finally {
loading.value = false
}
}
/* ================= INIT ================= */
onMounted(() => {
loadLookups()
})
</script>