Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -124,9 +124,21 @@
|
||||
:rows-per-page-options="[0]"
|
||||
hide-bottom
|
||||
>
|
||||
<template #body-cell="props">
|
||||
<q-td :props="props" :class="props.col.classes">
|
||||
<template v-if="props.col.name === 'open'">
|
||||
<template #body="props">
|
||||
<q-tr
|
||||
:id="rowDomId(props.row)"
|
||||
:props="props"
|
||||
class="rdp-data-row"
|
||||
@mouseenter="showMembersPopup(props.row)"
|
||||
@mouseleave="scheduleHideMembersPopup"
|
||||
>
|
||||
<q-td
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
:class="col.classes"
|
||||
>
|
||||
<template v-if="col.name === 'open'">
|
||||
<div class="text-center">
|
||||
<q-btn
|
||||
icon="open_in_new"
|
||||
@@ -141,10 +153,10 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="isPermissionColumn(props.col.name)">
|
||||
<template v-else-if="isPermissionColumn(col.name)">
|
||||
<div class="text-center">
|
||||
<q-checkbox
|
||||
:model-value="Boolean(props.value)"
|
||||
:model-value="Boolean(col.value)"
|
||||
disable
|
||||
dense
|
||||
/>
|
||||
@@ -152,12 +164,43 @@
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
{{ props.value }}
|
||||
{{ col.value }}
|
||||
</template>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<q-menu
|
||||
v-model="membersPopupOpen"
|
||||
:target="membersPopupTarget"
|
||||
no-parent-event
|
||||
anchor="center right"
|
||||
self="center left"
|
||||
:offset="[8, 0]"
|
||||
class="rdp-members-popup"
|
||||
@mouseenter="cancelHideMembersPopup"
|
||||
@mouseleave="scheduleHideMembersPopup"
|
||||
>
|
||||
<div class="rdp-members-popup__header">
|
||||
<div class="text-weight-bold">{{ hoveredRow?.role_title }}</div>
|
||||
<div class="text-caption text-grey-7">{{ hoveredRow?.department_title }}</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<q-list v-if="hoveredMembers.length" dense class="rdp-members-popup__list">
|
||||
<q-item v-for="member in hoveredMembers" :key="member.id">
|
||||
<q-item-section avatar class="rdp-member-id">{{ member.id }}</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ member.full_name || member.username }}</q-item-label>
|
||||
<q-item-label caption>{{ member.username }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<div v-else class="q-pa-sm text-caption text-grey-7">
|
||||
Bu grupta aktif kullanici bulunmuyor.
|
||||
</div>
|
||||
</q-menu>
|
||||
|
||||
<q-banner v-if="store.error" class="bg-red text-white q-mt-sm">
|
||||
Hata: {{ store.error }}
|
||||
</q-banner>
|
||||
@@ -171,7 +214,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useQuasar } from 'quasar'
|
||||
import { usePermission } from 'src/composables/usePermission'
|
||||
@@ -187,6 +230,10 @@ const selectedModules = ref([])
|
||||
const selectedActionsByModule = ref({})
|
||||
const activeModuleCode = ref('')
|
||||
const allowEmptySelection = ref(false)
|
||||
const membersPopupOpen = ref(false)
|
||||
const membersPopupTarget = ref(false)
|
||||
const hoveredRow = ref(null)
|
||||
let membersPopupHideTimer = null
|
||||
|
||||
const actionLabelMap = {
|
||||
update: 'Güncelleme',
|
||||
@@ -428,6 +475,37 @@ const tableRows = computed(() =>
|
||||
}))
|
||||
)
|
||||
|
||||
const hoveredMembers = computed(() => hoveredRow.value?.members || [])
|
||||
|
||||
function rowDomId (row) {
|
||||
const roleID = String(row?.role_id || '0').replace(/[^a-zA-Z0-9_-]/g, '-')
|
||||
const departmentCode = String(row?.department_code || '').replace(/[^a-zA-Z0-9_-]/g, '-')
|
||||
return `rdp-row-${roleID}-${departmentCode}`
|
||||
}
|
||||
|
||||
function cancelHideMembersPopup () {
|
||||
if (!membersPopupHideTimer) return
|
||||
clearTimeout(membersPopupHideTimer)
|
||||
membersPopupHideTimer = null
|
||||
}
|
||||
|
||||
function showMembersPopup (row) {
|
||||
cancelHideMembersPopup()
|
||||
hoveredRow.value = row
|
||||
membersPopupTarget.value = `#${rowDomId(row)}`
|
||||
membersPopupOpen.value = true
|
||||
}
|
||||
|
||||
function scheduleHideMembersPopup () {
|
||||
cancelHideMembersPopup()
|
||||
membersPopupHideTimer = setTimeout(() => {
|
||||
membersPopupOpen.value = false
|
||||
hoveredRow.value = null
|
||||
membersPopupTarget.value = false
|
||||
membersPopupHideTimer = null
|
||||
}, 180)
|
||||
}
|
||||
|
||||
function isPermissionColumn (name) {
|
||||
return String(name || '').startsWith('perm_')
|
||||
}
|
||||
@@ -472,6 +550,10 @@ onMounted(async () => {
|
||||
syncSelections()
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
cancelHideMembersPopup()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -571,6 +653,30 @@ onMounted(async () => {
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
.rdp-data-row {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.rdp-members-popup {
|
||||
min-width: 280px;
|
||||
max-width: 380px;
|
||||
}
|
||||
|
||||
.rdp-members-popup__header {
|
||||
padding: 10px 12px 8px;
|
||||
}
|
||||
|
||||
.rdp-members-popup__list {
|
||||
max-height: 360px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.rdp-member-id {
|
||||
min-width: 48px;
|
||||
color: #1976d2;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.rdp-table :deep(.q-checkbox__inner) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user