Fix: Usar DropdownMenu de radix-vue para menú de configuració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
- Reemplaza dropdown manual por componente DropdownMenu con radix-vue - Agrega avoid-collisions y collision-padding para posicionamiento automático - El menú ahora se ajusta automáticamente cuando no hay espacio horizontal - Actualiza DropdownMenuItem para soportar prop 'as' y 'href' para enlaces
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, computed, watch } from 'vue';
|
||||
import { Button, Badge, Input, Card, CardHeader, CardTitle, CardActions, CardContent, Textarea } from '@/components/ui';
|
||||
import { Button, Badge, Input, Card, CardHeader, CardTitle, CardActions, CardContent, Textarea, DropdownMenu, DropdownMenuItem, DropdownMenuSeparator } from '@/components/ui';
|
||||
import EventCard from '@/components/EventCard.vue';
|
||||
import UserCard from '@/components/UserCard.vue';
|
||||
import DispositivoCard from '@/components/DispositivoCard.vue';
|
||||
@@ -45,7 +45,6 @@ const mainCollapsed = ref(false);
|
||||
const layoutMode = ref('user');
|
||||
const theme = ref(localStorage.getItem('theme') || 'dark');
|
||||
const statusText = ref('OK');
|
||||
const showSettingsMenu = ref(false);
|
||||
const showInfoModal = ref(false);
|
||||
|
||||
async function fetchUsers() {
|
||||
@@ -305,13 +304,12 @@ function openAddGuest() {
|
||||
userFormModel.value = { username:'', password:'', vlan:'5', disabled:false, etiquetas: ['invitado'] };
|
||||
showUserForm.value = true;
|
||||
}
|
||||
function toggleSettingsMenu() { showSettingsMenu.value = !showSettingsMenu.value; }
|
||||
const showRawDb = ref(false);
|
||||
const rawDbFullscreen = ref(false);
|
||||
function openRawDb() { showSettingsMenu.value = false; showRawDb.value = true; }
|
||||
function openRawDb() { showRawDb.value = true; }
|
||||
function closeRawDb() { showRawDb.value = false; }
|
||||
const showVlan = ref(false);
|
||||
function openVlanForm() { showSettingsMenu.value = false; showVlan.value = true; }
|
||||
function openVlanForm() { showVlan.value = true; }
|
||||
function closeVlan() { showVlan.value = false; }
|
||||
function onVlanCreated() { showVlan.value = false; }
|
||||
const showDevice = ref(false);
|
||||
@@ -426,22 +424,23 @@ async function handleUserFormSubmit(data) {
|
||||
<img class="size-4 opacity-90" src="/icons/guest.svg" alt="invitado"> Invitado
|
||||
</Button>
|
||||
<UserDropdown />
|
||||
<div class="relative">
|
||||
<Button @click="toggleSettingsMenu">
|
||||
<DropdownMenu align="end">
|
||||
<template #trigger>
|
||||
<Button>
|
||||
<img class="size-4 opacity-90" src="/icons/settings.svg" alt="config"> Configuración
|
||||
</Button>
|
||||
<div v-if="showSettingsMenu" class="absolute right-0 top-full mt-1.5 glass-card p-1.5 min-w-[200px] shadow-lg border border-pink-200 dark:border-pink-600/50 z-50 space-y-1">
|
||||
<Button variant="ghost" class="w-full justify-start" @click="openRawDb">ver rawDB</Button>
|
||||
<Button variant="ghost" class="w-full justify-start" @click="openVlanForm">crear VLAN</Button>
|
||||
<hr class="border-border my-1" />
|
||||
<Button as="a" variant="ghost" class="w-full justify-start" href="/api/users.csv">Exportar usuarios CSV</Button>
|
||||
<Button as="a" variant="ghost" class="w-full justify-start" href="/api/devices.csv">Exportar dispositivos CSV</Button>
|
||||
<Button as="a" variant="ghost" class="w-full justify-start" href="/api/vlans.csv">Exportar VLANs CSV</Button>
|
||||
<Button variant="ghost" class="w-full justify-start" @click="openImport('users')">Importar usuarios CSV</Button>
|
||||
<Button variant="ghost" class="w-full justify-start" @click="openImport('devices')">Importar dispositivos CSV</Button>
|
||||
<Button variant="ghost" class="w-full justify-start" @click="openImport('vlans')">Importar VLANs CSV</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<DropdownMenuItem @click="openRawDb">ver rawDB</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="openVlanForm">crear VLAN</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem as="a" href="/api/users.csv">Exportar usuarios CSV</DropdownMenuItem>
|
||||
<DropdownMenuItem as="a" href="/api/devices.csv">Exportar dispositivos CSV</DropdownMenuItem>
|
||||
<DropdownMenuItem as="a" href="/api/vlans.csv">Exportar VLANs CSV</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem @click="openImport('users')">Importar usuarios CSV</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="openImport('devices')">Importar dispositivos CSV</DropdownMenuItem>
|
||||
<DropdownMenuItem @click="openImport('vlans')">Importar VLANs CSV</DropdownMenuItem>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
DropdownMenuContent
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps({
|
||||
defineProps({
|
||||
align: {
|
||||
type: String,
|
||||
default: 'end'
|
||||
@@ -14,6 +14,14 @@ const props = defineProps({
|
||||
side: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
sideOffset: {
|
||||
type: Number,
|
||||
default: 6
|
||||
},
|
||||
collisionPadding: {
|
||||
type: [Number, Object],
|
||||
default: 8
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -28,7 +36,9 @@ const props = defineProps({
|
||||
<DropdownMenuContent
|
||||
:align="align"
|
||||
:side="side"
|
||||
:side-offset="6"
|
||||
:side-offset="sideOffset"
|
||||
:collision-padding="collisionPadding"
|
||||
:avoid-collisions="true"
|
||||
class="z-50 min-w-[180px] glass-card p-1.5 shadow-lg border border-pink-200 dark:border-pink-600/50 animate-slide-in"
|
||||
>
|
||||
<slot />
|
||||
|
||||
@@ -6,7 +6,12 @@ import { cn } from '@/lib/utils';
|
||||
const props = defineProps({
|
||||
disabled: Boolean,
|
||||
danger: Boolean,
|
||||
class: String
|
||||
class: String,
|
||||
as: {
|
||||
type: [String, Object],
|
||||
default: undefined
|
||||
},
|
||||
href: String
|
||||
});
|
||||
|
||||
const classes = computed(() => cn(
|
||||
@@ -17,10 +22,12 @@ const classes = computed(() => cn(
|
||||
props.danger && 'hover:border-red-400/30 hover:text-red-400',
|
||||
props.class
|
||||
));
|
||||
|
||||
const elementAs = computed(() => props.as || (props.href ? 'a' : undefined));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuItem :disabled="disabled" :class="classes">
|
||||
<DropdownMenuItem :as="elementAs" :href="href" :disabled="disabled" :class="classes">
|
||||
<slot />
|
||||
</DropdownMenuItem>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user