mejoras UI 4
This commit is contained in:
35
frontend/src/components/DispositivoCard.vue
Normal file
35
frontend/src/components/DispositivoCard.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="row">
|
||||
<b>{{ device.nombre || device.mac }}</b>
|
||||
<span class="chip">{{ device.mac }}</span>
|
||||
<span v-if="connectedCount>0 || connected" class="chip" style="background: rgba(255,127,187,.2); border-color: rgba(255,127,187,.5);">Conectado</span>
|
||||
<span class="spacer"></span>
|
||||
<button v-if="!simple" class="icon-btn" @click="$emit('toggleExpand')">{{ expanded ? 'Contraer' : 'Expandir' }}</button>
|
||||
</div>
|
||||
<div v-if="expanded && users && users.length" style="margin-top:8px;">
|
||||
<div class="grid">
|
||||
<UserCard v-for="u in users" :key="u.username" :item="u" :devicesById="devicesById" :expandable="false" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import UserCard from './UserCard.vue';
|
||||
|
||||
const props = defineProps({
|
||||
device: { type: Object, required: true },
|
||||
users: { type: Array, default: () => [] },
|
||||
devicesById: { type: Object, default: () => ({}) },
|
||||
simple: { type: Boolean, default: false },
|
||||
connected: { type: Boolean, default: false },
|
||||
expanded: { type: Boolean, default: false }
|
||||
});
|
||||
const connectedCount = computed(() => {
|
||||
if (!props.users || !props.users.length) return props.connected ? 1 : 0;
|
||||
const id = props.device.id;
|
||||
return props.users.filter(u => Array.isArray(u.dispositivos_conectados) && u.dispositivos_conectados.includes(id)).length;
|
||||
});
|
||||
</script>
|
||||
@@ -1,26 +0,0 @@
|
||||
import { defineComponent, h } from 'vue';
|
||||
import htm from 'htm';
|
||||
const html = htm.bind(h);
|
||||
|
||||
export default defineComponent({
|
||||
name: 'UserCard',
|
||||
props: { item: { type: Object, required: true }, mode: { type: String, default: 'user' } },
|
||||
emits: ['toggleDisable', 'remove', 'edit'],
|
||||
setup(props, { emit }) {
|
||||
function toggle() { emit('toggleDisable', props.item); }
|
||||
function remove() { emit('remove', props.item); }
|
||||
function edit() { emit('edit', props.item); }
|
||||
return () => html`<div class="card">
|
||||
<div class="row">
|
||||
<b>${props.mode === 'user' ? props.item.username : (props.item.device || props.item.username)}</b>
|
||||
<span class="chip">VLAN ${props.item.vlan}</span>
|
||||
${props.item.disabled ? html`<span class="chip" style="color:#b33">deshabilitado</span>` : html`<span class="chip">activo</span>`}
|
||||
<span class="spacer"></span>
|
||||
<button class="icon-btn" onClick=${edit}>Editar</button>
|
||||
<button class="icon-btn" onClick=${toggle}>${props.item.disabled ? 'Habilitar' : 'Deshabilitar'}</button>
|
||||
<button class="icon-btn" onClick=${remove}>Eliminar</button>
|
||||
</div>
|
||||
<div class="muted" style="margin-top:6px; font-size:12px;">${props.item.devices ? props.item.devices.length : 0} dispositivos</div>
|
||||
</div>`;
|
||||
}
|
||||
});
|
||||
40
frontend/src/components/UserCard.vue
Normal file
40
frontend/src/components/UserCard.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="row">
|
||||
<b>{{ item.username }}</b>
|
||||
<span class="chip">VLAN {{ item.vlan }}</span>
|
||||
<span class="chip" :style="item.disabled ? 'color:#b33' : ''">{{ item.disabled ? 'deshabilitado' : 'activo' }}</span>
|
||||
<span class="spacer"></span>
|
||||
<button class="icon-btn" @click="$emit('edit', item)">Editar</button>
|
||||
<button class="icon-btn" @click="$emit('toggleDisable', item)">{{ item.disabled ? 'Habilitar' : 'Deshabilitar' }}</button>
|
||||
<button class="icon-btn" @click="$emit('remove', item)">Eliminar</button>
|
||||
<button v-if="expandable" class="icon-btn" @click="$emit('toggleExpand')">{{ expanded ? 'Contraer' : 'Expandir' }}</button>
|
||||
</div>
|
||||
<div v-if="expanded && deviceList.length" style="margin-top:8px;">
|
||||
<div class="grid">
|
||||
<DispositivoCard v-for="d in deviceList" :key="d.id" :device="d" :connected="isConnected(d.id)" simple />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import DispositivoCard from './DispositivoCard.vue';
|
||||
|
||||
const props = defineProps({
|
||||
item: { type: Object, required: true },
|
||||
devicesById: { type: Object, default: () => ({}) },
|
||||
expandable: { type: Boolean, default: true },
|
||||
expanded: { type: Boolean, default: false }
|
||||
});
|
||||
|
||||
const deviceList = computed(() => {
|
||||
const ids = props.item.dispositivos_utilizados || [];
|
||||
return ids.map(id => props.devicesById[id]).filter(Boolean);
|
||||
});
|
||||
|
||||
function isConnected(id) {
|
||||
return Array.isArray(props.item.dispositivos_conectados) && props.item.dispositivos_conectados.includes(id);
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user