This commit is contained in:
2026-02-11 17:46:22 +03:00
commit eacfacb13b
266 changed files with 51337 additions and 0 deletions

View 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>