feat(studio): un solo set de iconos en vez de emojis mezclados con símbolos
En la misma pantalla convivían dos lenguajes: emojis a color (🌙 📊 🧠 ✍️ 📄 🌐 🔁) y símbolos tipográficos monocromos (✎ ✕ ← ↻ ⚠ ⬇ ✓). Eso se lee como descuido, y encima los emojis los dibuja el sistema operativo — el mismo panel se ve distinto en Mac, en Windows y en Android, sin que podamos hacer nada. Ahora hay un set propio de iconos SVG de trazo: mismo grosor de línea, misma caja, y heredan currentColor, así que toman el color del texto que los rodea y funcionan igual en tema claro y oscuro. Al lado uno de otro tienen el mismo peso visual, que es lo que hacía falta. El emoji suelto de la pantalla de inicio pasa a ser Umi, que ya es el personaje del producto. Un detalle de implementación que costó dos intentos: los iconos NO pueden declararse como cadenas de HTML para v-html. Dentro de un <svg>, v-html parsea como HTML y los <path> quedan sin el namespace de SVG: aparecen en el DOM pero no dibujan nada, así que la primera versión se veía perfecta en el código y en blanco en pantalla. Van declarados como pares [etiqueta, atributos] para que Vue los cree con el namespace correcto. Y AgenteDetail usaba cinco iconos sin importar el componente. Verificado ahora sobre todos los archivos: cada componente usado está importado donde se usa. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
002b75e71b
commit
ee9bb2cfb7
@@ -5,6 +5,7 @@ import { api } from '../lib/api.js'
|
||||
import { apiUmind, contexto } from '../lib/contexto.js'
|
||||
import UiEmptyState from '../components/ui/UiEmptyState.vue'
|
||||
import UiMascota from '../components/ui/UiMascota.vue'
|
||||
import UiIcono from '../components/ui/UiIcono.vue'
|
||||
|
||||
const props = defineProps({
|
||||
tenantId: { type: String, required: true },
|
||||
@@ -414,7 +415,7 @@ async function enviarChatPrueba() {
|
||||
const r = await api.post(apiUmind('/umind/chat'), { agente_id: agenteIdNum.value, session_id: chatSessionId, mensaje: texto })
|
||||
chatMensajes.value.push({ role: 'assistant', content: r.respuesta })
|
||||
} catch (e) {
|
||||
chatMensajes.value.push({ role: 'assistant', content: `⚠️ ${e.message}` })
|
||||
chatMensajes.value.push({ role: 'assistant', content: `⚠ ${e.message}` })
|
||||
} finally {
|
||||
chatEnviando.value = false
|
||||
}
|
||||
@@ -507,7 +508,7 @@ watch(
|
||||
<!-- Un archivo que se reenvía sirve para justificar el gasto puertas
|
||||
adentro; un panel al que hay que entrar, no. -->
|
||||
<a :href="urlReporte" class="btn-ghost shrink-0" title="Conversaciones y consumo del mes en Excel">
|
||||
⬇ Reporte del mes
|
||||
<UiIcono nombre="descargar" :tam="15" /> Reporte del mes
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -532,12 +533,12 @@ watch(
|
||||
<div class="card p-4 mb-4">
|
||||
<div class="flex gap-1 mb-3">
|
||||
<button
|
||||
v-for="[k, l] in [['texto', '✍️ Escribir'], ['archivo', '📄 Subir archivo'], ['url', '🌐 Sitio web']]"
|
||||
v-for="[k, ico, l] in [['texto', 'escribir', 'Escribir'], ['archivo', 'archivo', 'Subir archivo'], ['url', 'sitio', 'Sitio web']]"
|
||||
:key="k"
|
||||
class="px-3 py-1.5 rounded-lg text-sm"
|
||||
class="px-3 py-1.5 rounded-lg text-sm inline-flex items-center gap-1.5"
|
||||
:class="fuenteNueva === k ? 'bg-brand text-white font-medium' : 'text-tenue hover:text-texto'"
|
||||
@click="fuenteNueva = k"
|
||||
>{{ l }}</button>
|
||||
><UiIcono :nombre="ico" :tam="15" /> {{ l }}</button>
|
||||
</div>
|
||||
|
||||
<!-- Lo que el dueño sabe y no está escrito en ningún lado. -->
|
||||
@@ -616,7 +617,7 @@ watch(
|
||||
class="text-xs text-tenue hover:text-texto"
|
||||
:title="d.auto_actualizar ? 'Dejar de releer sola' : 'Releer el sitio cada semana'"
|
||||
@click="alternarAuto(d)"
|
||||
>{{ d.auto_actualizar ? '🔁 auto' : '↻ manual' }}</button>
|
||||
><UiIcono :nombre="d.auto_actualizar ? 'auto' : 'refrescar'" :tam="13" class="mr-1" />{{ d.auto_actualizar ? 'auto' : 'manual' }}</button>
|
||||
<!-- Solo lo que tiene texto propio guardado: una URL se rehace
|
||||
crawleando, editarla a mano se perdería en la próxima pasada. -->
|
||||
<button
|
||||
@@ -740,7 +741,7 @@ watch(
|
||||
<label class="label flex items-center gap-1">
|
||||
<input v-model="p.requerido" type="checkbox" /> req.
|
||||
</label>
|
||||
<button type="button" class="text-red-400 text-xs" @click="quitarParametro(i)">✕</button>
|
||||
<button type="button" class="text-red-400 text-xs" @click="quitarParametro(i)"><UiIcono nombre="cerrar" :tam="13" /></button>
|
||||
</div>
|
||||
<p v-if="toolForm.parametros.length === 0" class="text-xs text-gray-400">Sin parámetros.</p>
|
||||
</div>
|
||||
@@ -788,7 +789,8 @@ watch(
|
||||
:class="widgetCopiado ? 'bg-green-600 text-white' : 'bg-brand hover:bg-brand-dark text-white'"
|
||||
@click="copiarWidget"
|
||||
>
|
||||
{{ widgetCopiado ? '✓ Copiado' : 'Copiar código' }}
|
||||
<UiIcono v-if="widgetCopiado" nombre="ok" :tam="14" />
|
||||
{{ widgetCopiado ? 'Copiado' : 'Copiar código' }}
|
||||
</button>
|
||||
</div>
|
||||
<p class="label mb-2">
|
||||
|
||||
Reference in New Issue
Block a user