Fix VM search displaying

This commit is contained in:
Joshua Boniface 2025-03-02 13:54:25 -05:00
parent 0107197b2b
commit f879fddd95
3 changed files with 114 additions and 43 deletions

View File

@ -14,7 +14,7 @@
<input
type="text"
placeholder="Search VMs..."
:value="!showList ? selectedVM : modelValue"
:value="inputValue"
@input="handleSearch"
@focus="handleFocus"
@blur="handleBlur"
@ -91,7 +91,7 @@
v-for="vm in filteredVMs"
:key="vm.name"
class="vm-list-item"
:class="{ 'active': selectedVM === vm.name }"
:class="{ 'active': selectedVM === vm.name || vmFromUrl === vm.name }"
@click="handleVMSelect(vm)"
>
<div class="vm-item-content">
@ -130,9 +130,22 @@ const props = defineProps({
selectedVM: {
type: String,
default: ''
},
vmFromUrl: {
type: String,
default: ''
}
});
// Direct debug log of props
console.log('VMSearchBar props:', {
modelValue: props.modelValue,
showList: props.showList,
selectedVM: props.selectedVM,
vmFromUrl: props.vmFromUrl,
vmListLength: props.vmList.length
});
const emit = defineEmits([
'update:modelValue',
'search',
@ -159,6 +172,31 @@ const appliedFilters = ref({
// Add new ref for tracking search active state
const searchActive = ref(false);
// Local ref to track input value
const inputValue = ref('');
// Watch both showList and selectedVM to update input value
watch([() => props.showList, () => props.selectedVM, () => props.vmFromUrl],
([showList, selectedVM, vmFromUrl]) => {
console.log('Watch triggered:', { showList, selectedVM, vmFromUrl });
const effectiveVM = selectedVM || vmFromUrl;
if (!showList && effectiveVM) {
// When list is closed, show selected VM or VM from URL
inputValue.value = effectiveVM;
} else {
// When list is open, show search query
inputValue.value = props.modelValue || '';
}
}, { immediate: true }
);
// Watch modelValue to update input when searching
watch(() => props.modelValue, (newVal) => {
if (props.showList) {
inputValue.value = newVal || '';
}
});
// Calculate available states from vmList
const availableStates = computed(() => {
const states = new Set();
@ -274,9 +312,11 @@ const filteredVMs = computed(() => {
// Methods
const handleSearch = (event) => {
searchActive.value = true;
emit('update:modelValue', event.target.value);
emit('search', event.target.value);
if (props.showList) {
searchActive.value = true;
emit('update:modelValue', event.target.value);
emit('search', event.target.value);
}
};
const handleFocus = (event) => {
@ -294,6 +334,7 @@ const clearSearch = () => {
};
const toggleList = () => {
console.log('toggleList called, showList:', props.showList);
searchActive.value = false;
if (props.showList) {
// If we're closing the list, clear the search
@ -303,6 +344,8 @@ const toggleList = () => {
};
const handleVMSelect = (vm) => {
console.log('handleVMSelect called with:', vm);
emit('update:modelValue', ''); // Clear search query
emit('select-vm', vm);
};
@ -347,6 +390,15 @@ onMounted(() => {
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
});
// Add a watcher for selectedVM with a debug log
watch(() => props.selectedVM, (newVal, oldVal) => {
console.log('VMSearchBar selectedVM changed:', { newVal, oldVal });
// Update input value when selectedVM changes
if (!props.showList && newVal) {
inputValue.value = newVal;
}
}, { immediate: true });
</script>
<style scoped>

View File

@ -1,11 +1,13 @@
<template>
<div class="overview-container">
<VMSearchBar
:key="searchBarKey"
v-model="searchQuery"
:selected-vm="selectedVM"
:vm-from-url="route.query.vm"
:show-list="showVMList"
:show-clear-button="true"
:vm-list="props.vmData"
:selected-vm="selectedVM"
@search="handleSearch"
@focus="handleSearchFocus"
@blur="handleSearchBlur"
@ -139,11 +141,15 @@ const props = defineProps({
type: Object,
required: true,
default: () => ({})
},
loading: {
type: Boolean,
default: false
}
});
// State
const selectedVM = ref('');
// Use ref and sync with route
const selectedVM = ref(route.query.vm || '');
const searchQuery = ref('');
const showVMList = ref(true);
const searchActive = ref(false);
@ -194,21 +200,11 @@ const toggleVMList = () => {
// Select a VM
const selectVM = (vm) => {
isLoading.value = true;
nextTick(() => {
const vmExists = props.vmData.some(vm => vm.name === vm.name);
if (vmExists) {
selectedVM.value = vm.name;
invalidVMSelected.value = false;
showVMList.value = false;
} else {
selectedVM.value = '';
invalidVMSelected.value = true;
showVMList.value = false;
}
router.push({ query: { vm: vm.name } });
isLoading.value = false;
});
// Update the ref first
selectedVM.value = vm.name;
invalidVMSelected.value = false;
showVMList.value = false;
router.push({ query: { vm: vm.name } });
};
// Clear search
@ -219,22 +215,22 @@ const clearSearch = () => {
// Lifecycle hooks
onMounted(() => {
// Initialize with URL state if present
console.log('VMOverview mounted, route.query.vm:', route.query.vm);
const vmFromQuery = route.query.vm;
if (vmFromQuery) {
console.log('Setting selectedVM to:', vmFromQuery);
selectedVM.value = vmFromQuery;
isLoading.value = true;
// Check if we already have data
showVMList.value = false;
// If we have data, verify the VM exists
if (props.vmData.length) {
selectVM({ name: vmFromQuery });
} else {
// If no data yet, set the VM but mark as pending verification
selectedVM.value = vmFromQuery;
showVMList.value = false;
// Don't set invalidVMSelected yet - wait for data
const vmExists = props.vmData.some(v => v.name === vmFromQuery);
invalidVMSelected.value = !vmExists;
}
isLoading.value = false;
} else if (props.vmData.length > 0) {
showVMList.value = true;
selectedVM.value = '';
invalidVMSelected.value = false;
}
});
@ -243,16 +239,19 @@ onUnmounted(() => {
// Remove event listeners and clean up resources
});
// Watch for route changes to update selected VM
// Watch for route changes to update selectedVM
watch(() => route.query.vm, (newVm) => {
// Explicitly update the ref when route changes
selectedVM.value = newVm || '';
if (newVm) {
selectVM({ name: newVm });
// Just update UI state, don't trigger another route change
invalidVMSelected.value = false;
showVMList.value = false;
} else if (props.vmData.length > 0) {
selectedVM.value = '';
showVMList.value = true;
invalidVMSelected.value = false;
}
});
}, { immediate: true });
// Watch for changes in the VM list visibility
watch(() => showVMList.value, (isVisible) => {
@ -266,17 +265,32 @@ watch(() => showVMList.value, (isVisible) => {
// Add watcher for vmData to handle loading state
watch(() => props.vmData, (newData) => {
if (isLoading.value && selectedVM.value) {
if (selectedVM.value && newData.length) {
const vmExists = newData.some(vm => vm.name === selectedVM.value);
if (!vmExists) {
invalidVMSelected.value = true;
} else {
invalidVMSelected.value = false;
}
isLoading.value = false;
invalidVMSelected.value = !vmExists;
}
}, { immediate: true });
// Add debug watcher
watch(() => selectedVM.value, (newVal) => {
console.log('VMOverview selectedVM changed:', newVal);
}, { immediate: true });
// Watch for vmData changes to update VMSearchBar
watch(() => props.vmData, (newData) => {
if (newData.length && selectedVM.value) {
console.log('VM data loaded, updating VMSearchBar with selectedVM:', selectedVM.value);
// Force a refresh of the VMSearchBar by toggling a key
nextTick(() => {
// This will force the VMSearchBar to re-render with the correct data
searchBarKey.value = Date.now();
});
}
});
// Add a key to force VMSearchBar to re-render when data changes
const searchBarKey = ref(0);
// Helper functions
const getStateColor = (state) => {
if (!state) return '';

View File

@ -5,6 +5,7 @@
:vmData="vmData"
:metricsData="metricsData"
:clusterData="clusterData"
:loading="isLoading"
/>
</div>
</template>
@ -29,6 +30,10 @@ const props = defineProps({
type: Object,
required: true,
default: () => ({})
},
isLoading: {
type: Boolean,
default: false
}
});
</script>