fix(studio): cambiar de tenant o de agente no recargaba la pantalla

Al navegar de /tenants/2 a /tenants/3, vue-router reusa la misma instancia
del componente porque es la misma ruta con otro parámetro. onMounted no
vuelve a dispararse, así que la vista seguía mostrando los agentes del
tenant anterior.

Las tres vistas tenían el mismo problema: TenantAgentes, AgenteDetail y
Uso. Ahora reaccionan al parámetro (watch con immediate) en vez de al
montaje.

En AgenteDetail se limpia el estado antes de pedir los datos nuevos: si no,
durante la carga se ven los documentos, canales y conversaciones del agente
anterior bajo el nombre del nuevo, que es peor que una pantalla vacía.

Verificado navegando de verdad entre dos tenants con agentes distintos: la
lista pasa de "Ventas T2" a "Soporte T3 / Cobros T3".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-15 08:01:37 -05:00
co-authored by Claude Sonnet 5
parent a25329c7b1
commit ad3458bb71
6 changed files with 64 additions and 39 deletions
+22 -3
View File
@@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue' import { computed, ref, watch } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { api } from '../lib/api.js' import { api } from '../lib/api.js'
import { apiUmind, contexto } from '../lib/contexto.js' import { apiUmind, contexto } from '../lib/contexto.js'
@@ -330,13 +330,32 @@ function formatearFecha(iso) {
} }
} }
onMounted(async () => { // Se observan los dos parámetros: al saltar de un agente a otro (o a un
// agente de otro tenant) vue-router reusa la instancia y onMounted no vuelve
// a correr, así que la pantalla quedaba con los datos del agente anterior.
watch(
() => [props.tenantId, props.agenteId],
async () => {
error.value = ''
// Se limpia antes de pedir: si no, durante la carga se ven los datos del
// agente anterior bajo el nombre del nuevo.
agente.value = null
documentos.value = []
sesiones.value = []
historial.value = []
sesionActiva.value = null
tools.value = []
canales.value = []
conexiones.value = []
eventos.value = []
try { try {
await Promise.all([cargarAgente(), cargarDocumentos(), cargarSesiones(), cargarTools(), cargarCanales(), cargarConexiones(), cargarEventos()]) await Promise.all([cargarAgente(), cargarDocumentos(), cargarSesiones(), cargarTools(), cargarCanales(), cargarConexiones(), cargarEventos()])
} catch (e) { } catch (e) {
error.value = e.message error.value = e.message
} }
}) },
{ immediate: true },
)
</script> </script>
<template> <template>
+6 -2
View File
@@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue' import { computed, ref, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { api } from '../lib/api.js' import { api } from '../lib/api.js'
import { apiUmind, contexto } from '../lib/contexto.js' import { apiUmind, contexto } from '../lib/contexto.js'
@@ -127,7 +127,11 @@ async function eliminarAgente(a) {
await cargar() await cargar()
} }
onMounted(cargar) // watch con immediate en vez de onMounted: al navegar entre /tenants/2 y
// /tenants/3 vue-router reusa la misma instancia del componente, así que
// onMounted no vuelve a dispararse y la pantalla seguía mostrando los agentes
// del tenant anterior.
watch(() => props.id, cargar, { immediate: true })
</script> </script>
<template> <template>
+4 -2
View File
@@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue' import { computed, ref, watch } from 'vue'
import { api } from '../lib/api.js' import { api } from '../lib/api.js'
import { apiUmind } from '../lib/contexto.js' import { apiUmind } from '../lib/contexto.js'
import UiEmptyState from '../components/ui/UiEmptyState.vue' import UiEmptyState from '../components/ui/UiEmptyState.vue'
@@ -76,7 +76,9 @@ function atajo(dias) {
cargar() cargar()
} }
onMounted(cargar) // Ver el comentario en TenantAgentes.vue: la instancia se reusa al cambiar
// de tenant, así que hay que reaccionar al parámetro y no al montaje.
watch(() => props.id, cargar, { immediate: true })
</script> </script>
<template> <template>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>uMind Studio</title> <title>uMind Studio</title>
<script type="module" crossorigin src="/orchestrator/assets/index-CXtokcMG.js"></script> <script type="module" crossorigin src="/orchestrator/assets/index-DsDQ67K1.js"></script>
<link rel="stylesheet" crossorigin href="/orchestrator/assets/index-DyYio0bD.css"> <link rel="stylesheet" crossorigin href="/orchestrator/assets/index-DyYio0bD.css">
</head> </head>
<!-- Sin clase de fondo: el color lo pone body en style.css desde los tokens, <!-- Sin clase de fondo: el color lo pone body en style.css desde los tokens,