Feature: Filtros toggleables para todos los tipos de sesión
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 26s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 26s
- Activas: visibles por defecto, click para ocultar - Finalizadas: ocultas por defecto, click para mostrar - Stale: ocultas por defecto, click para mostrar - Indicador visual con ícono ojo abierto/cerrado y ring highlight - Mensaje informativo de sesiones ocultas por tipo
This commit is contained in:
@@ -261,10 +261,16 @@ const pagedDevices = computed(() => devicesAll.value.slice(devicePage.value*page
|
||||
watch([devicesAll, () => layoutMode.value], () => { devicePage.value = 0; });
|
||||
|
||||
const sessionPage = ref(0);
|
||||
const showActiveSessions = ref(true);
|
||||
const showStaleSessions = ref(false);
|
||||
const showStoppedSessions = ref(false);
|
||||
const filteredSessions = computed(() => {
|
||||
if (showStaleSessions.value) return sessions.value;
|
||||
return sessions.value.filter(s => s.status !== 'stale');
|
||||
return sessions.value.filter(s => {
|
||||
if (s.status === 'active' && !showActiveSessions.value) return false;
|
||||
if (s.status === 'stale' && !showStaleSessions.value) return false;
|
||||
if (s.status === 'stopped' && !showStoppedSessions.value) return false;
|
||||
return true;
|
||||
});
|
||||
});
|
||||
const pagedSessions = computed(() => filteredSessions.value.slice(sessionPage.value*pageSize, sessionPage.value*pageSize + pageSize));
|
||||
watch([filteredSessions, () => layoutMode.value], () => { sessionPage.value = 0; });
|
||||
@@ -544,14 +550,40 @@ async function handleUserFormSubmit(data) {
|
||||
<div v-else class="space-y-3">
|
||||
<!-- Stats -->
|
||||
<div class="flex flex-wrap gap-3 mb-4">
|
||||
<Badge variant="pink" class="text-sm py-1.5 px-3">
|
||||
<svg class="size-4 mr-1.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<polyline points="12 6 12 12 16 14"></polyline>
|
||||
<Badge
|
||||
:variant="showActiveSessions ? 'pink' : 'secondary'"
|
||||
class="text-sm py-1.5 px-3 cursor-pointer select-none transition-all"
|
||||
:class="showActiveSessions ? 'ring-2 ring-pink-400/50' : 'opacity-60 hover:opacity-100'"
|
||||
@click="showActiveSessions = !showActiveSessions"
|
||||
:title="showActiveSessions ? 'Click para ocultar sesiones activas' : 'Click para mostrar sesiones activas'"
|
||||
>
|
||||
<svg v-if="showActiveSessions" class="size-3.5 mr-1.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
</svg>
|
||||
<svg v-else class="size-3.5 mr-1.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path>
|
||||
<line x1="1" y1="1" x2="23" y2="23"></line>
|
||||
</svg>
|
||||
Activas: {{ sessionStats.active }}
|
||||
</Badge>
|
||||
<Badge variant="secondary" class="text-sm py-1.5 px-3">Finalizadas: {{ sessionStats.stopped }}</Badge>
|
||||
<Badge
|
||||
:variant="showStoppedSessions ? 'secondary' : 'secondary'"
|
||||
class="text-sm py-1.5 px-3 cursor-pointer select-none transition-all"
|
||||
:class="showStoppedSessions ? 'ring-2 ring-muted/50' : 'opacity-60 hover:opacity-100'"
|
||||
@click="showStoppedSessions = !showStoppedSessions"
|
||||
:title="showStoppedSessions ? 'Click para ocultar sesiones finalizadas' : 'Click para mostrar sesiones finalizadas'"
|
||||
>
|
||||
<svg v-if="showStoppedSessions" class="size-3.5 mr-1.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
</svg>
|
||||
<svg v-else class="size-3.5 mr-1.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path>
|
||||
<line x1="1" y1="1" x2="23" y2="23"></line>
|
||||
</svg>
|
||||
Finalizadas: {{ sessionStats.stopped }}
|
||||
</Badge>
|
||||
<Badge
|
||||
:variant="showStaleSessions ? 'warning' : 'secondary'"
|
||||
class="text-sm py-1.5 px-3 cursor-pointer select-none transition-all"
|
||||
@@ -589,7 +621,13 @@ async function handleUserFormSubmit(data) {
|
||||
<!-- Sessions Grid -->
|
||||
<div v-if="loading.sessions" class="text-muted">Cargando sesiones...</div>
|
||||
<div v-else-if="!filteredSessions.length" class="text-muted text-center py-8">
|
||||
{{ sessions.length ? 'No hay sesiones activas (hay ' + sessionStats.stale + ' stale ocultas)' : 'No hay sesiones' }}
|
||||
<template v-if="!sessions.length">No hay sesiones</template>
|
||||
<template v-else>
|
||||
No hay sesiones visibles
|
||||
<span v-if="sessionStats.active && !showActiveSessions" class="block text-xs mt-1">{{ sessionStats.active }} activas ocultas</span>
|
||||
<span v-if="sessionStats.stopped && !showStoppedSessions" class="block text-xs mt-1">{{ sessionStats.stopped }} finalizadas ocultas</span>
|
||||
<span v-if="sessionStats.stale && !showStaleSessions" class="block text-xs mt-1">{{ sessionStats.stale }} stale ocultas</span>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="grid grid-cols-[repeat(auto-fill,minmax(320px,1fr))] gap-3">
|
||||
<Card v-for="s in pagedSessions" :key="s.id" :class="['p-4', s.status === 'active' && 'border-pink-400/30 bg-pink-400/5']">
|
||||
|
||||
Reference in New Issue
Block a user