193 lines
5.4 KiB
Vue
193 lines
5.4 KiB
Vue
<template>
|
||
<q-page
|
||
v-if="canReadUser"
|
||
class="q-pa-md user-sync-page"
|
||
>
|
||
|
||
<div class="row items-center justify-between q-mb-md">
|
||
<div class="text-h6 text-primary">👤 Kullanıcı Yönetimi</div>
|
||
<q-btn
|
||
v-if="canUpdateUser"
|
||
color="primary"
|
||
icon="sync"
|
||
label="Sync Now"
|
||
:loading="store.loading"
|
||
:disable="store.loading || !canUpdateUser"
|
||
@click="store.syncNow"
|
||
/>
|
||
</div>
|
||
|
||
<q-separator />
|
||
|
||
<div class="row q-col-gutter-md q-mt-md">
|
||
<!-- 🔹 PostgreSQL Kullanıcıları -->
|
||
<div class="col-6">
|
||
<q-card flat bordered>
|
||
<q-card-section class="bg-primary text-white text-subtitle1">
|
||
PostgreSQL Kullanıcıları
|
||
</q-card-section>
|
||
|
||
<q-table
|
||
:rows="store.pgUsers"
|
||
:columns="pgColumns"
|
||
row-key="id"
|
||
flat
|
||
dense
|
||
bordered
|
||
separator="cell"
|
||
>
|
||
<template v-slot:body-cell-sync_status="props">
|
||
<q-td :props="props">
|
||
<q-chip
|
||
:color="statusColor(props.row.sync_status)"
|
||
text-color="white"
|
||
dense
|
||
>
|
||
{{ props.row.sync_status }}
|
||
</q-chip>
|
||
</q-td>
|
||
</template>
|
||
|
||
<template v-slot:body-cell-actions="props">
|
||
<q-td :props="props">
|
||
<q-btn
|
||
v-if="canUpdateUser"
|
||
dense flat icon="link"
|
||
color="primary"
|
||
size="sm"
|
||
@click="openMapDialog(props.row)"
|
||
:disable="store.loading || !canUpdateUser"
|
||
/>
|
||
<q-btn
|
||
v-if="canUpdateUser"
|
||
dense flat icon="link_off"
|
||
color="negative"
|
||
size="sm"
|
||
@click="store.unmap(props.row.id)"
|
||
:disable="store.loading || !props.row.mssql_username || !canUpdateUser"
|
||
/>
|
||
</q-td>
|
||
</template>
|
||
</q-table>
|
||
</q-card>
|
||
</div>
|
||
|
||
<!-- 🔸 MSSQL Kullanıcıları -->
|
||
<div class="col-6">
|
||
<q-card flat bordered>
|
||
<q-card-section class="bg-secondary text-white text-subtitle1">
|
||
MSSQL Kullanıcıları
|
||
</q-card-section>
|
||
|
||
<q-table
|
||
:rows="store.msUsers"
|
||
:columns="msColumns"
|
||
row-key="username"
|
||
flat
|
||
dense
|
||
bordered
|
||
separator="cell"
|
||
>
|
||
<template v-slot:body-cell-is_blocked="props">
|
||
<q-td :props="props">
|
||
<q-chip
|
||
:color="props.row.is_blocked ? 'negative' : 'positive'"
|
||
text-color="white"
|
||
dense
|
||
>
|
||
{{ props.row.is_blocked ? 'Engelli' : 'Aktif' }}
|
||
</q-chip>
|
||
</q-td>
|
||
</template>
|
||
</q-table>
|
||
</q-card>
|
||
</div>
|
||
</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 { onMounted } from 'vue'
|
||
import { useUserSyncStore } from 'src/stores/userSyncStore'
|
||
import { Dialog } from 'quasar'
|
||
import { usePermission } from 'src/composables/usePermission'
|
||
|
||
const { canRead, canUpdate } = usePermission()
|
||
const canReadUser = canRead('user')
|
||
const canUpdateUser = canUpdate('user')
|
||
|
||
const store = useUserSyncStore()
|
||
|
||
const pgColumns = [
|
||
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
|
||
{ name: 'code', label: 'Kodu', field: 'code', align: 'left' },
|
||
{ name: 'full_name', label: 'Ad Soyad', field: 'full_name', align: 'left' },
|
||
{ name: 'email', label: 'E-posta', field: 'email', align: 'left' },
|
||
{ name: 'mssql_username', label: 'MSSQL Kullanıcı', field: 'mssql_username', align: 'left' },
|
||
{ name: 'sync_status', label: 'Durum', field: 'sync_status', align: 'center' },
|
||
{ name: 'actions', label: 'İşlemler', field: 'actions', align: 'center' }
|
||
]
|
||
|
||
const msColumns = [
|
||
{ name: 'username', label: 'Kullanıcı Adı', field: 'username', align: 'left' },
|
||
{ name: 'first_name', label: 'Ad', field: 'first_name', align: 'left' },
|
||
{ name: 'last_name', label: 'Soyad', field: 'last_name', align: 'left' },
|
||
{ name: 'email', label: 'E-posta', field: 'email', align: 'left' },
|
||
{ name: 'is_blocked', label: 'Durum', field: 'is_blocked', align: 'center' }
|
||
]
|
||
|
||
function statusColor(status) {
|
||
switch (status) {
|
||
case 'synced': return 'positive'
|
||
case 'manual': return 'primary'
|
||
case 'blocked': return 'warning'
|
||
case 'orphan': return 'negative'
|
||
default: return 'grey'
|
||
}
|
||
}
|
||
|
||
function openMapDialog(pgUser) {
|
||
if (!canUpdateUser.value) {
|
||
return
|
||
}
|
||
|
||
Dialog.create({
|
||
title: 'Kullanıcı Eşleme',
|
||
message: 'Bu PostgreSQL kullanıcısını hangi MSSQL kullanıcısına bağlamak istiyorsunuz?',
|
||
options: {
|
||
type: 'radio',
|
||
model: '',
|
||
items: store.msUsers.map(u => ({ label: `${u.username} (${u.email})`, value: u.username }))
|
||
},
|
||
cancel: true,
|
||
persistent: true
|
||
}).onOk(val => {
|
||
store.map(pgUser.id, val)
|
||
})
|
||
}
|
||
|
||
onMounted(() => {
|
||
if (canReadUser.value) {
|
||
store.loadDummy()
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.user-sync-page {
|
||
background: #fafafa;
|
||
}
|
||
.q-card-section {
|
||
font-weight: 600;
|
||
}
|
||
</style>
|