fix(crm): guardar permisos de rol y recargar roles/usuarios tras refresh

- role-permissions.assign enviaba permission_id en el body pero el backend lo
  espera como query param → 422 silencioso; el permiso no se guardaba. Ahora va
  en la query y se confirma con un toast al marcar cada permiso (auto-guardado).
- Roles y Usuarios recargaban solo con el evento companyChanged, que no dispara
  en la hidratación inicial; por eso tras refrescar no aparecían hasta re-elegir
  la compañía. Se cambia a un $effect que reacciona a la compañía activa.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ernesto Herrera
2026-07-20 06:43:35 -06:00
parent 0cffd351df
commit 71be225b33
3 changed files with 27 additions and 22 deletions

View File

@@ -48,7 +48,11 @@ export const rolePermissionsAPI = {
companyId: number,
data: AssignPermissionData
): Promise<RolePermission> {
const response = await api.post(`/v1/core/permissions/roles/${roleId}/permissions?company_id=${companyId}`, data);
// El backend recibe permission_id como query param (no en el body).
const response = await api.post(
`/v1/core/permissions/roles/${roleId}/permissions?permission_id=${data.permission_id}&company_id=${companyId}`,
{}
);
return response.data;
},

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { Shield, Plus, Trash2, ChevronRight, ChevronDown } from '@lucide/svelte';
import * as Card from '$lib/components/ui/card';
import { Button } from '$lib/components/ui/button';
@@ -57,18 +56,19 @@
}
}
function onCompanyChanged() {
// Recarga los roles cuando cambia la compañía activa —incluida la hidratación
// inicial tras refrescar (en onMount el store aún no tenía compañía, por eso
// antes no aparecían hasta re-seleccionarla).
$effect(() => {
const id = companyId;
expandedRoleId = null;
rolePerms = {};
void load();
}
onMount(() => {
void load();
if (typeof window !== 'undefined') window.addEventListener('companyChanged', onCompanyChanged);
});
onDestroy(() => {
if (typeof window !== 'undefined') window.removeEventListener('companyChanged', onCompanyChanged);
if (id) {
void load();
} else {
roles = [];
loading = false;
}
});
async function createRole() {
@@ -136,6 +136,7 @@
rolePerms[roleId]?.delete(perm.id);
}
rolePerms = { ...rolePerms };
toast.success(checked ? 'Permiso agregado' : 'Permiso quitado');
} catch (e) {
toast.error('No se pudo actualizar el permiso');
} finally {

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { Users, X, UserPlus, Copy, Check } from '@lucide/svelte';
import { Button } from '$lib/components/ui/button';
import * as Card from '$lib/components/ui/card';
@@ -61,15 +60,16 @@
}
}
function onCompanyChanged() {
void load();
}
onMount(() => {
void load();
if (typeof window !== 'undefined') window.addEventListener('companyChanged', onCompanyChanged);
});
onDestroy(() => {
if (typeof window !== 'undefined') window.removeEventListener('companyChanged', onCompanyChanged);
// Recarga al cambiar la compañía activa —incluida la hidratación inicial tras
// refrescar (antes no cargaba hasta re-seleccionar la compañía).
$effect(() => {
const id = companyId;
if (id) {
void load();
} else {
users = [];
loading = false;
}
});
async function assignRole(user: User, roleIdRaw: string) {