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

172
ui/src/pages/UserSync.vue Normal file
View File

@@ -0,0 +1,172 @@
<template>
<q-page 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
color="primary"
icon="sync"
label="Sync Now"
:loading="store.loading"
@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
dense flat icon="link"
color="primary"
size="sm"
@click="openMapDialog(props.row)"
:disable="store.loading"
/>
<q-btn
dense flat icon="link_off"
color="negative"
size="sm"
@click="store.unmap(props.row.id)"
:disable="!props.row.mssql_username"
/>
</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>
</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, canWrite, canUpdate } = usePermission()
const canReadOrder = canRead('order')
const canWriteOrder = canWrite('order')
const canUpdateOrder = canUpdate('order')
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) {
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(() => {
store.loadDummy()
})
</script>
<style scoped>
.user-sync-page {
background: #fafafa;
}
.q-card-section {
font-weight: 600;
}
</style>