ilk
This commit is contained in:
301
ui/src/pages/PermissionMatrix.vue
Normal file
301
ui/src/pages/PermissionMatrix.vue
Normal file
@@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<q-page 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
|
||||
color="primary"
|
||||
icon="save"
|
||||
label="Kaydet"
|
||||
:disable="!dirty"
|
||||
@click="save"
|
||||
/>
|
||||
|
||||
</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, canWrite, canUpdate } = usePermission()
|
||||
|
||||
const canReadOrder = canRead('order')
|
||||
const canWriteOrder = canWrite('order')
|
||||
const canUpdateOrder = canUpdate('order')
|
||||
|
||||
|
||||
/* ================= 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>
|
||||
Reference in New Issue
Block a user