refactor: improve SelectMenu implementation with object binding
All checks were successful
build-and-deploy / build (push) Successful in 44s
build-and-deploy / deploy (push) Successful in 4s

- Change from ID-based selection to full object binding
- Add custom label templates to display proper text
- Simplify computed properties and watchers
- Improve user experience with proper label display
This commit is contained in:
2025-10-13 18:46:52 -06:00
parent ce69a62336
commit 3dd24e33c9

View File

@@ -15,34 +15,40 @@
<!-- Database Selector -->
<UFieldGroup label="Base de datos">
<USelectMenu
v-model="selectedDatabaseId"
:options="databaseOptions"
v-model="selectedDatabase"
:options="databases"
placeholder="Seleccionar base de datos"
:loading="loadingDatabases"
:disabled="loadingDatabases"
value-attribute="value"
option-attribute="label"
/>
option-attribute="name"
>
<template #label>
{{ selectedDatabase?.name || 'Seleccionar base de datos' }}
</template>
</USelectMenu>
</UFieldGroup>
<!-- Table Selector -->
<UFieldGroup label="Tabla" v-if="selectedDatabaseId">
<UFieldGroup label="Tabla" v-if="selectedDatabase">
<USelectMenu
v-model="selectedTableId"
:options="tableOptions"
v-model="selectedTable"
:options="tables"
placeholder="Seleccionar tabla"
:loading="loadingTables"
:disabled="loadingTables || !selectedDatabaseId"
value-attribute="value"
option-attribute="label"
/>
:disabled="loadingTables || !selectedDatabase"
option-attribute="name"
>
<template #label>
{{ selectedTable?.display_name || selectedTable?.name || 'Seleccionar tabla' }}
</template>
</USelectMenu>
</UFieldGroup>
<!-- Load Data Button -->
<UButton
v-if="selectedTableId"
v-if="selectedTable"
:loading="loadingData"
:disabled="!selectedTableId"
:disabled="!selectedTable"
@click="loadTableData"
color="primary"
icon="i-lucide-refresh-cw"
@@ -147,7 +153,7 @@
</UCard>
<!-- Empty State -->
<UCard v-else-if="selectedTableId" class="brand-card border border-transparent">
<UCard v-else-if="selectedTable" class="brand-card border border-transparent">
<div class="py-10 text-center text-sm text-[var(--brand-text-muted)]">
<UIcon name="i-lucide-inbox" class="mx-auto mb-4 size-12 text-[var(--brand-text-muted)]" />
<h3 class="text-lg font-semibold text-[var(--brand-text)] mb-2">No hay datos disponibles</h3>
@@ -175,8 +181,8 @@ definePageMeta({
})
// State
const selectedDatabaseId = ref<number | null>(null)
const selectedTableId = ref<number | null>(null)
const selectedDatabase = ref<any | null>(null)
const selectedTable = ref<any | null>(null)
const loadingDatabases = ref(false)
const loadingTables = ref(false)
const loadingData = ref(false)
@@ -190,23 +196,11 @@ const tableData = ref<any[]>([])
const visibleColumns = ref<string[]>([])
// Computed
const databaseOptions = computed(() => {
return databases.value.map(db => ({
label: db.name,
value: db.id
}))
})
const tableOptions = computed(() => {
return tables.value.map(table => ({
label: `${table.display_name || table.name} (${table.row_count || 0} registros)`,
value: table.id
}))
})
const selectedDatabaseId = computed(() => selectedDatabase.value?.id)
const selectedTableId = computed(() => selectedTable.value?.id)
const selectedTableName = computed(() => {
const table = tables.value.find(t => t.id === selectedTableId.value)
return table ? (table.display_name || table.name) : ''
return selectedTable.value ? (selectedTable.value.display_name || selectedTable.value.name) : ''
})
const tableColumns = computed(() => {
@@ -252,7 +246,7 @@ async function loadDatabases() {
// Auto-select first database
if (databases.value.length > 0) {
selectedDatabaseId.value = databases.value[0].id
selectedDatabase.value = databases.value[0]
}
} catch (err: any) {
error.value = `Error al cargar bases de datos: ${err.message || 'Error desconocido'}`
@@ -263,15 +257,15 @@ async function loadDatabases() {
}
async function loadTables() {
if (!selectedDatabaseId.value) return
if (!selectedDatabase.value) return
loadingTables.value = true
error.value = null
selectedTableId.value = null
selectedTable.value = null
tableData.value = []
try {
const response = await $fetch(`/api/metabase/tables/${selectedDatabaseId.value}`)
const response = await $fetch(`/api/metabase/tables/${selectedDatabase.value.id}`)
const metadata = response as any
// Metabase returns tables in the 'tables' property
@@ -339,7 +333,7 @@ function toggleColumn(columnKey: string) {
}
// Watchers
watch(selectedDatabaseId, () => {
watch(selectedDatabase, () => {
loadTables()
})