121 lines
3.6 KiB
Vue
121 lines
3.6 KiB
Vue
<script setup lang="ts">
|
|
import { Icon } from '@iconify/vue';
|
|
import type { RoleAccessItem } from '~/types/setting/rolePermission';
|
|
|
|
const props = defineProps<{
|
|
item: RoleAccessItem;
|
|
level: number;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'toggle', payload: { id: number; key: 'read' | 'create' | 'update' | 'delete'; value: boolean }): void;
|
|
}>();
|
|
|
|
const onToggle = (key: 'read' | 'create' | 'update' | 'delete', value: boolean) => {
|
|
if (props.item.permission.disable) return;
|
|
emit('toggle', { id: props.item.id, key, value });
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
:style="{ marginLeft: (level > 0 ? 40 : 0) + 'px' }"
|
|
:class="{ 'is-child': level > 0 }"
|
|
class="permission-row-container"
|
|
>
|
|
<v-card class="permission-card mb-1" elevation="0">
|
|
<v-card-text class="pa-5">
|
|
<div class="d-flex align-center">
|
|
<div class="d-flex align-center flex-grow-1">
|
|
<v-icon v-if="level > 0" class="me-2" size="18">mdi-subdirectory-arrow-right</v-icon>
|
|
|
|
<v-tooltip location="bottom" :text="item.active ? 'Aktif' : 'Tidak Aktif'">
|
|
<template #activator="{ props: activatorProps }">
|
|
<v-avatar v-bind="activatorProps" :color="item.active ? 'primary' : 'muted'" size="40" class="me-3">
|
|
<Icon v-if="item.icon" :icon="'solar:' + item.icon" width="24" />
|
|
<v-icon v-else size="24">mdi-shield-account</v-icon>
|
|
</v-avatar>
|
|
</template>
|
|
</v-tooltip>
|
|
|
|
<div class="flex-grow-1">
|
|
<div class="d-flex align-center">
|
|
<h6 class="text-subtitle-1 font-weight-semibold">{{ item.name }}</h6>
|
|
</div>
|
|
<p class="text-muted mb-0">{{ item.url }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="perm-cell">
|
|
<v-checkbox-btn
|
|
:model-value="item.permission.read"
|
|
density="compact"
|
|
color="primary"
|
|
:disabled="item.permission.disable"
|
|
@update:modelValue="(v) => onToggle('read', Boolean(v))"
|
|
/>
|
|
</div>
|
|
<div class="perm-cell">
|
|
<v-checkbox-btn
|
|
:model-value="item.permission.create"
|
|
density="compact"
|
|
color="primary"
|
|
:disabled="item.permission.disable"
|
|
@update:modelValue="(v) => onToggle('create', Boolean(v))"
|
|
/>
|
|
</div>
|
|
<div class="perm-cell">
|
|
<v-checkbox-btn
|
|
:model-value="item.permission.update"
|
|
density="compact"
|
|
color="primary"
|
|
:disabled="item.permission.disable"
|
|
@update:modelValue="(v) => onToggle('update', Boolean(v))"
|
|
/>
|
|
</div>
|
|
<div class="perm-cell">
|
|
<v-checkbox-btn
|
|
:model-value="item.permission.delete"
|
|
density="compact"
|
|
color="primary"
|
|
:disabled="item.permission.disable"
|
|
@update:modelValue="(v) => onToggle('delete', Boolean(v))"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
|
|
<div v-if="item.children?.length" class="children-container">
|
|
<PermissionRow
|
|
v-for="child in item.children"
|
|
:key="child.id"
|
|
:item="child"
|
|
:level="level + 1"
|
|
@toggle="emit('toggle', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.permission-row-container {
|
|
position: relative;
|
|
}
|
|
.permission-card {
|
|
cursor: default;
|
|
}
|
|
|
|
.perm-cell {
|
|
width: 84px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.perm-cell .v-selection-control {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
</style>
|