feature-comercial-module-ts #13
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<Toast />
|
||||||
<!-- Encabezado principal -->
|
<!-- Encabezado principal -->
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<h1 class="text-2xl md:text-3xl font-black text-slate-900 dark:text-white mb-1">Gestión de Roles y Permisos</h1>
|
<h1 class="text-2xl md:text-3xl font-black text-slate-900 dark:text-white mb-1">Gestión de Roles y Permisos</h1>
|
||||||
@ -11,30 +12,61 @@
|
|||||||
<div class="sticky top-20 z-10 flex flex-wrap items-center justify-between gap-4 bg-white/80 dark:bg-slate-900/80 backdrop-blur-md p-4 mb-6 rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm">
|
<div class="sticky top-20 z-10 flex flex-wrap items-center justify-between gap-4 bg-white/80 dark:bg-slate-900/80 backdrop-blur-md p-4 mb-6 rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm">
|
||||||
<div class="flex-1 min-w-[200px]">
|
<div class="flex-1 min-w-[200px]">
|
||||||
<p class="text-lg font-bold text-slate-900 dark:text-white">Permisos para <span class="text-primary">{{ activeRoleName }}</span></p>
|
<p class="text-lg font-bold text-slate-900 dark:text-white">Permisos para <span class="text-primary">{{ activeRoleName }}</span></p>
|
||||||
<p class="text-sm text-slate-500 dark:text-slate-400">Hay cambios sin guardar</p>
|
<p class="text-sm text-slate-500 dark:text-slate-400">
|
||||||
|
{{ getPermissionStats().enabled }} de {{ getPermissionStats().total }} permisos seleccionados
|
||||||
|
<span v-if="hasUnsavedChanges" class="text-amber-600 dark:text-amber-400 font-medium"> • Cambios sin guardar</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<Button label="Cancelar" class="min-w-[84px]" outlined @click="onCancel" />
|
<Button
|
||||||
<Button label="Guardar Cambios" class="min-w-[84px] px-5" @click="onSave" />
|
label="Cancelar"
|
||||||
|
class="min-w-[84px]"
|
||||||
|
outlined
|
||||||
|
:disabled="saving"
|
||||||
|
@click="onCancel"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
:label="saving ? 'Guardando...' : 'Guardar Cambios'"
|
||||||
|
:icon="saving ? 'pi pi-spin pi-spinner' : ''"
|
||||||
|
class="min-w-[84px] px-5"
|
||||||
|
:disabled="saving || !hasUnsavedChanges"
|
||||||
|
@click="onSave"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Loading State -->
|
||||||
|
<div v-if="loading" class="flex items-center justify-center py-12">
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
|
||||||
|
<p class="text-slate-500 dark:text-slate-400">Cargando permisos...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Empty State -->
|
||||||
|
<div v-else-if="modules.length === 0" class="text-center py-12">
|
||||||
|
<p class="text-slate-500 dark:text-slate-400">No se encontraron tipos de permisos</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Permissions Content -->
|
<!-- Permissions Content -->
|
||||||
<div class="space-y-6">
|
<div v-else class="space-y-6">
|
||||||
<div v-for="module in modules" :key="module.name" class="bg-white dark:bg-slate-900/50 rounded-xl border border-slate-200 dark:border-slate-800">
|
<div v-for="module in modules" :key="module.id" class="bg-white dark:bg-slate-900/50 rounded-xl border border-slate-200 dark:border-slate-800">
|
||||||
<div class="flex items-center justify-between p-4 border-b border-slate-200 dark:border-slate-800">
|
<div class="flex items-center justify-between p-4 border-b border-slate-200 dark:border-slate-800">
|
||||||
<h4 class="text-base font-bold text-slate-800 dark:text-slate-200">{{ module.label }}</h4>
|
<h4 class="text-base font-bold text-slate-800 dark:text-slate-200">{{ module.label }}</h4>
|
||||||
<template v-if="module.name === 'reportes'">
|
<Button
|
||||||
<Button label="DESELECCIONAR TODO" text class="text-xs font-bold text-primary" @click="deselectAll(module)" />
|
:label="areAllSelected(module) ? 'DESELECCIONAR TODO' : 'SELECCIONAR TODO'"
|
||||||
</template>
|
text
|
||||||
<template v-else>
|
:class="areAllSelected(module) ? 'text-xs font-bold text-primary' : 'text-xs font-bold'"
|
||||||
<Button label="SELECCIONAR TODO" text class="text-xs font-bold" @click="selectAll(module)" />
|
@click="toggleAllPermissions(module)"
|
||||||
</template>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
|
<div class="p-4 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
<div v-for="perm in module.permissions" :key="perm.key" class="flex items-center justify-between bg-slate-50 dark:bg-slate-800/50 p-3 rounded-lg">
|
<div v-for="perm in module.permissions" :key="perm.id" class="flex items-center justify-between bg-slate-50 dark:bg-slate-800/50 p-3 rounded-lg">
|
||||||
<p class="text-sm font-medium text-slate-700 dark:text-slate-300">{{ perm.label }}</p>
|
<p class="text-sm font-medium text-slate-700 dark:text-slate-300">{{ perm.label }}</p>
|
||||||
<InputSwitch v-model="perm.enabled" />
|
<InputSwitch
|
||||||
|
:modelValue="rolePermissions[perm.id] || false"
|
||||||
|
@update:modelValue="(value: boolean) => rolePermissions[perm.id] = value"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -44,70 +76,291 @@
|
|||||||
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import Button from 'primevue/button';
|
import Button from 'primevue/button';
|
||||||
import InputSwitch from 'primevue/inputswitch';
|
import InputSwitch from 'primevue/inputswitch';
|
||||||
|
import Toast from 'primevue/toast';
|
||||||
|
import { useToast } from 'primevue/usetoast';
|
||||||
|
import { permissionsService } from '../services/permissionsService';
|
||||||
|
import { roleService } from '../services/roleService';
|
||||||
|
import type { PermissionType, UpdateRolePermissionsData } from '../types/permissions';
|
||||||
|
import type { Role } from '../types/role';
|
||||||
|
|
||||||
// Mock roles list
|
const toast = useToast();
|
||||||
const rolesList = ref([
|
const route = useRoute();
|
||||||
{ id: 1, name: 'Administrador General', icon: 'shield_person', active: true },
|
const router = useRouter();
|
||||||
{ id: 2, name: 'Gerente de Tienda', icon: 'storefront', active: false },
|
|
||||||
{ id: 3, name: 'Cajero', icon: 'point_of_sale', active: false },
|
|
||||||
{ id: 4, name: 'Bodeguero', icon: 'inventory_2', active: false },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const activeRoleName = computed(() => {
|
// State management
|
||||||
const active = rolesList.value.find(r => r.active);
|
const loading = ref(false);
|
||||||
return active ? active.name + (active.id === 1 ? ' *' : '') : '';
|
const saving = ref(false);
|
||||||
|
const permissionTypes = ref<PermissionType[]>([]);
|
||||||
|
const rolePermissions = ref<{ [key: number]: boolean }>({});
|
||||||
|
const currentRole = ref<Role | null>(null);
|
||||||
|
const originalPermissions = ref<{ [key: number]: boolean }>({});
|
||||||
|
|
||||||
|
// Props para recibir el rol desde el componente padre (opcional, también funciona con route params)
|
||||||
|
interface Props {
|
||||||
|
roleId?: number;
|
||||||
|
roleName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
roleId: undefined,
|
||||||
|
roleName: 'Rol sin nombre'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mock modules and permissions
|
// Obtener roleId desde props o route params
|
||||||
const modules = ref([
|
const currentRoleId = computed(() => {
|
||||||
{
|
return props.roleId || (route.params.id ? Number(route.params.id) : undefined);
|
||||||
name: 'ventas',
|
});
|
||||||
label: 'Módulo de Ventas (POS)',
|
|
||||||
permissions: [
|
|
||||||
{ key: 'acceso_tpv', label: 'Acceso al TPV', enabled: true },
|
|
||||||
{ key: 'crear_ventas', label: 'Crear Ventas', enabled: true },
|
|
||||||
{ key: 'aplicar_descuentos', label: 'Aplicar Descuentos', enabled: true },
|
|
||||||
{ key: 'realizar_devoluciones', label: 'Realizar Devoluciones', enabled: true },
|
|
||||||
{ key: 'anular_tickets', label: 'Anular Tickets', enabled: false },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'inventario',
|
|
||||||
label: 'Módulo de Inventario',
|
|
||||||
permissions: [
|
|
||||||
{ key: 'ver_productos', label: 'Ver Productos', enabled: true },
|
|
||||||
{ key: 'crear_editar_productos', label: 'Crear/Editar Productos', enabled: true },
|
|
||||||
{ key: 'ajustes_stock', label: 'Ajustes de Stock', enabled: true },
|
|
||||||
{ key: 'gestionar_proveedores', label: 'Gestionar Proveedores', enabled: false },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'reportes',
|
|
||||||
label: 'Módulo de Reportes',
|
|
||||||
permissions: [
|
|
||||||
{ key: 'acceder_reportes', label: 'Acceder a Reportes', enabled: true },
|
|
||||||
{ key: 'ver_dashboard', label: 'Ver Dashboard', enabled: true },
|
|
||||||
{ key: 'exportar_datos', label: 'Exportar Datos', enabled: true },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
function onAddRole() {
|
const activeRoleName = computed(() => {
|
||||||
// TODO: Acción para añadir nuevo rol
|
if (currentRole.value) {
|
||||||
|
return currentRole.value.description || currentRole.value.name;
|
||||||
}
|
}
|
||||||
|
return props.roleName;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Detectar si hay cambios sin guardar
|
||||||
|
const hasUnsavedChanges = computed(() => {
|
||||||
|
return JSON.stringify(rolePermissions.value) !== JSON.stringify(originalPermissions.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Computed para los módulos con permisos habilitados/deshabilitados
|
||||||
|
const modules = computed(() => {
|
||||||
|
return permissionTypes.value.map(permissionType => ({
|
||||||
|
id: permissionType.id,
|
||||||
|
name: permissionType.name.toLowerCase().replace(/\s+/g, '_'),
|
||||||
|
label: `Módulo de ${permissionType.name}`,
|
||||||
|
permissions: permissionType.permissions.map(permission => ({
|
||||||
|
id: permission.id,
|
||||||
|
key: permission.name,
|
||||||
|
label: permission.description || permission.name,
|
||||||
|
// Remover la propiedad enabled ya que usamos rolePermissions directamente en el template
|
||||||
|
}))
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Lifecycle hooks
|
||||||
|
onMounted(async () => {
|
||||||
|
await loadInitialData();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
async function loadInitialData() {
|
||||||
|
await Promise.all([
|
||||||
|
loadPermissionTypes(),
|
||||||
|
currentRoleId.value ? loadRoleData(currentRoleId.value) : Promise.resolve()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRoleData(roleId: number) {
|
||||||
|
try {
|
||||||
|
console.log('Cargando datos del rol:', roleId);
|
||||||
|
// Aquí podrías llamar a un endpoint para obtener los datos del rol si fuera necesario
|
||||||
|
// Por ahora, solo simulamos que tenemos el rol
|
||||||
|
currentRole.value = {
|
||||||
|
id: roleId,
|
||||||
|
name: `Rol ${roleId}`,
|
||||||
|
description: `Rol ${roleId}`,
|
||||||
|
guard_name: 'api',
|
||||||
|
created_at: '',
|
||||||
|
updated_at: ''
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error al cargar datos del rol:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadPermissionTypes() {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const response = await permissionsService.getAllPermissionTypes();
|
||||||
|
|
||||||
|
if (response.data?.status === 'success') {
|
||||||
|
permissionTypes.value = response.data.data.models;
|
||||||
|
|
||||||
|
// Inicializar todos los permisos como deshabilitados por defecto
|
||||||
|
permissionTypes.value.forEach(permissionType => {
|
||||||
|
permissionType.permissions.forEach(permission => {
|
||||||
|
rolePermissions.value[permission.id] = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Si estamos editando un rol existente, cargar sus permisos específicos
|
||||||
|
console.log('Props roleId:', props.roleId, 'Route params id:', route.params.id, 'Computed currentRoleId:', currentRoleId.value);
|
||||||
|
if (currentRoleId.value) {
|
||||||
|
await loadRolePermissions(currentRoleId.value);
|
||||||
|
} else {
|
||||||
|
console.log('No se cargaron permisos específicos porque roleId no está definido');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Tipos de permisos cargados. Total de permisos disponibles:',
|
||||||
|
permissionTypes.value.reduce((total, type) => total + type.permissions.length, 0));
|
||||||
|
} else {
|
||||||
|
throw new Error('Respuesta inválida de la API');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error al cargar tipos de permisos:', error);
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: 'No se pudieron cargar los permisos del sistema',
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRolePermissions(roleId: number) {
|
||||||
|
try {
|
||||||
|
console.log('Cargando permisos específicos del rol:', roleId);
|
||||||
|
const response = await permissionsService.getRolePermissions(roleId);
|
||||||
|
|
||||||
|
if (response.data?.status === 'success') {
|
||||||
|
const roleSpecificPermissions = response.data.data.permissions;
|
||||||
|
|
||||||
|
// Crear un Set con los IDs de permisos que tiene el rol para búsqueda rápida
|
||||||
|
const rolePermissionIds = new Set(roleSpecificPermissions.map(perm => perm.id));
|
||||||
|
|
||||||
|
// Actualizar el estado de rolePermissions basado en la comparación
|
||||||
|
permissionTypes.value.forEach(permissionType => {
|
||||||
|
permissionType.permissions.forEach(permission => {
|
||||||
|
// Si el permiso está en los permisos del rol, marcarlo como habilitado
|
||||||
|
const isEnabled = rolePermissionIds.has(permission.id);
|
||||||
|
rolePermissions.value[permission.id] = isEnabled;
|
||||||
|
|
||||||
|
if (isEnabled) {
|
||||||
|
console.log(`Permiso habilitado: ${permission.name} (ID: ${permission.id})`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Permisos del rol cargados y comparados. Total permisos activos:', rolePermissionIds.size);
|
||||||
|
console.log('Estado actual de rolePermissions:', JSON.stringify(rolePermissions.value, null, 2));
|
||||||
|
|
||||||
|
// Guardar el estado original para detectar cambios
|
||||||
|
originalPermissions.value = { ...rolePermissions.value };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error al cargar permisos del rol:', error);
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: `No se pudieron cargar los permisos del rol`,
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onCancel() {
|
function onCancel() {
|
||||||
// TODO: Acción para cancelar edición
|
console.log('Cancelando edición de permisos');
|
||||||
|
|
||||||
|
// Si hay cambios sin guardar, mostrar advertencia
|
||||||
|
if (hasUnsavedChanges.value) {
|
||||||
|
// Podrías agregar un ConfirmDialog aquí para confirmar la cancelación
|
||||||
|
console.log('Hay cambios sin guardar, pero procediendo con cancelación');
|
||||||
|
|
||||||
|
toast.add({
|
||||||
|
severity: 'warn',
|
||||||
|
summary: 'Cambios Descartados',
|
||||||
|
detail: 'Los cambios no guardados se han descartado',
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function onSave() {
|
|
||||||
// TODO: Acción para guardar cambios
|
// Volver a la página de roles
|
||||||
|
router.push({ name: 'Roles' });
|
||||||
}
|
}
|
||||||
function selectAll(module: any) {
|
|
||||||
module.permissions.forEach((perm: any) => perm.enabled = true);
|
async function onSave() {
|
||||||
|
if (!currentRoleId.value) {
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: 'No se pudo identificar el rol a actualizar',
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
function deselectAll(module: any) {
|
|
||||||
module.permissions.forEach((perm: any) => perm.enabled = false);
|
try {
|
||||||
|
saving.value = true;
|
||||||
|
|
||||||
|
// Obtener los IDs de permisos habilitados
|
||||||
|
const enabledPermissions = Object.entries(rolePermissions.value)
|
||||||
|
.filter(([, enabled]) => enabled)
|
||||||
|
.map(([permissionId]) => parseInt(permissionId));
|
||||||
|
|
||||||
|
console.log('Guardando permisos para el rol:', currentRoleId.value, 'Permisos:', enabledPermissions);
|
||||||
|
|
||||||
|
// Llamar al servicio para actualizar permisos
|
||||||
|
const response = await permissionsService.updateRolePermissions(currentRoleId.value, {
|
||||||
|
permissions: enabledPermissions
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.data?.status === 'success') {
|
||||||
|
toast.add({
|
||||||
|
severity: 'success',
|
||||||
|
summary: 'Éxito',
|
||||||
|
detail: `Permisos actualizados correctamente. ${enabledPermissions.length} permisos asignados.`,
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
|
|
||||||
|
// Actualizar el estado original para reflejar los cambios guardados
|
||||||
|
originalPermissions.value = { ...rolePermissions.value };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new Error('Respuesta inválida del servidor');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Error al guardar permisos:', error);
|
||||||
|
|
||||||
|
let errorMessage = 'No se pudieron guardar los permisos';
|
||||||
|
|
||||||
|
// Manejar diferentes tipos de errores
|
||||||
|
if (error.response?.data?.message) {
|
||||||
|
errorMessage = error.response.data.message;
|
||||||
|
} else if (error.response?.data?.errors) {
|
||||||
|
// Si hay errores de validación, mostrar el primero
|
||||||
|
const firstError = Object.values(error.response.data.errors)[0];
|
||||||
|
errorMessage = Array.isArray(firstError) ? firstError[0] : firstError;
|
||||||
|
} else if (error.message) {
|
||||||
|
errorMessage = error.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error al Guardar',
|
||||||
|
detail: errorMessage,
|
||||||
|
life: 5000
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
saving.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computed function to check if all permissions in a module are selected
|
||||||
|
function areAllSelected(module: any) {
|
||||||
|
return module.permissions.length > 0 && module.permissions.every((perm: any) => rolePermissions.value[perm.id] === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle function that handles both select all and deselect all
|
||||||
|
function toggleAllPermissions(module: any) {
|
||||||
|
const shouldSelectAll = !areAllSelected(module);
|
||||||
|
|
||||||
|
module.permissions.forEach((perm: any) => {
|
||||||
|
rolePermissions.value[perm.id] = shouldSelectAll;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to get permission statistics
|
||||||
|
function getPermissionStats() {
|
||||||
|
const totalPermissions = Object.keys(rolePermissions.value).length;
|
||||||
|
const enabledPermissions = Object.values(rolePermissions.value).filter(Boolean).length;
|
||||||
|
return { total: totalPermissions, enabled: enabledPermissions };
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
60
src/modules/users/services/permissionsService.ts
Normal file
60
src/modules/users/services/permissionsService.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import api from "../../../services/api"
|
||||||
|
import type {
|
||||||
|
PermissionTypesResponse,
|
||||||
|
RolePermissionsResponse,
|
||||||
|
UpdateRolePermissionsData,
|
||||||
|
UpdateRolePermissionsResponse
|
||||||
|
} from '../types/permissions'
|
||||||
|
|
||||||
|
export const permissionsService = {
|
||||||
|
/**
|
||||||
|
* Obtiene todos los tipos de permisos con sus permisos asociados
|
||||||
|
* @returns Promise con la respuesta de la API conteniendo los tipos de permisos y permisos
|
||||||
|
*/
|
||||||
|
async getAllPermissionTypes() {
|
||||||
|
try {
|
||||||
|
console.log('Obteniendo todos los tipos de permisos...');
|
||||||
|
const response = await api.get<PermissionTypesResponse>('/api/permission-types/all-with-permissions');
|
||||||
|
console.log('Tipos de permisos obtenidos:', response.data);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error al obtener tipos de permisos:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtiene los permisos asignados a un rol específico
|
||||||
|
* @param roleId - ID del rol del cual obtener los permisos
|
||||||
|
* @returns Promise con la respuesta de la API conteniendo los permisos del rol
|
||||||
|
*/
|
||||||
|
async getRolePermissions(roleId: number) {
|
||||||
|
try {
|
||||||
|
console.log(`Obteniendo permisos del rol ${roleId}...`);
|
||||||
|
const response = await api.get<RolePermissionsResponse>(`/api/admin/roles/${roleId}/permissions`);
|
||||||
|
console.log(`Permisos del rol ${roleId} obtenidos:`, response.data);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error al obtener permisos del rol ${roleId}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actualiza los permisos asignados a un rol específico
|
||||||
|
* @param roleId - ID del rol al cual asignar los permisos
|
||||||
|
* @param data - Objeto con el array de IDs de permisos a asignar
|
||||||
|
* @returns Promise con la respuesta de la API
|
||||||
|
*/
|
||||||
|
async updateRolePermissions(roleId: number, data: UpdateRolePermissionsData) {
|
||||||
|
try {
|
||||||
|
console.log(`Actualizando permisos del rol ${roleId}...`, data);
|
||||||
|
const response = await api.put<UpdateRolePermissionsResponse>(`/api/admin/roles/${roleId}/permissions`, data);
|
||||||
|
console.log(`Permisos del rol ${roleId} actualizados:`, response.data);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error al actualizar permisos del rol ${roleId}:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
53
src/modules/users/types/permissions.d.ts
vendored
Normal file
53
src/modules/users/types/permissions.d.ts
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Base interfaces
|
||||||
|
export interface Permission {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
guard_name: string;
|
||||||
|
description: string;
|
||||||
|
permission_type_id: number;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PermissionType {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string | null;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
permissions: Permission[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission with pivot data for role-permission relationships
|
||||||
|
export interface PermissionWithPivot extends Permission {
|
||||||
|
pivot: {
|
||||||
|
role_id: number;
|
||||||
|
permission_id: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// API Response interfaces
|
||||||
|
export interface PermissionTypesResponse {
|
||||||
|
status: string;
|
||||||
|
data: {
|
||||||
|
models: PermissionType[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RolePermissionsResponse {
|
||||||
|
status: string;
|
||||||
|
data: {
|
||||||
|
permissions: PermissionWithPivot[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface for updating role permissions
|
||||||
|
export interface UpdateRolePermissionsData {
|
||||||
|
permissions: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateRolePermissionsResponse {
|
||||||
|
status: string;
|
||||||
|
message?: string;
|
||||||
|
data?: any;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user