.
This commit is contained in:
parent
bcf0e98b54
commit
adfc1d8269
@ -18,6 +18,7 @@
|
|||||||
@input="handleSearch"
|
@input="handleSearch"
|
||||||
@focus="handleFocus"
|
@focus="handleFocus"
|
||||||
@blur="handleBlur"
|
@blur="handleBlur"
|
||||||
|
@click="handleSearchClick"
|
||||||
class="form-control search-input"
|
class="form-control search-input"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@ -183,6 +184,15 @@ const vmListContainer = ref(null);
|
|||||||
// Add a ref to store the last search query
|
// Add a ref to store the last search query
|
||||||
const lastSearchQuery = ref('');
|
const lastSearchQuery = ref('');
|
||||||
|
|
||||||
|
// Add a flag to track if filtering should be applied
|
||||||
|
const filterActive = ref(false);
|
||||||
|
|
||||||
|
// Add a flag to track if a search has been performed
|
||||||
|
const hasSearched = ref(false);
|
||||||
|
|
||||||
|
// Add a flag to track if we should maintain focus after list refresh
|
||||||
|
const maintainFocusAfterRefresh = ref(false);
|
||||||
|
|
||||||
// Watch both showList and selectedVM to update input value
|
// Watch both showList and selectedVM to update input value
|
||||||
watch([() => props.showList, () => props.selectedVM, () => props.vmFromUrl, () => props.modelValue],
|
watch([() => props.showList, () => props.selectedVM, () => props.vmFromUrl, () => props.modelValue],
|
||||||
([showList, selectedVM, vmFromUrl, modelValue]) => {
|
([showList, selectedVM, vmFromUrl, modelValue]) => {
|
||||||
@ -301,8 +311,8 @@ const activeFiltersCount = computed(() => {
|
|||||||
const filteredVMs = computed(() => {
|
const filteredVMs = computed(() => {
|
||||||
let filtered = [...props.vmList];
|
let filtered = [...props.vmList];
|
||||||
|
|
||||||
// Always apply search filter if there's a query
|
// Apply search filter if filtering is active OR if a search has been performed
|
||||||
if (props.modelValue) {
|
if ((filterActive.value || hasSearched.value) && props.modelValue) {
|
||||||
const query = props.modelValue.toLowerCase();
|
const query = props.modelValue.toLowerCase();
|
||||||
filtered = filtered.filter(vm =>
|
filtered = filtered.filter(vm =>
|
||||||
vm.name.toLowerCase().includes(query)
|
vm.name.toLowerCase().includes(query)
|
||||||
@ -335,21 +345,45 @@ const filteredVMs = computed(() => {
|
|||||||
const handleSearch = (event) => {
|
const handleSearch = (event) => {
|
||||||
// Always update the model value to preserve search
|
// Always update the model value to preserve search
|
||||||
searchActive.value = true;
|
searchActive.value = true;
|
||||||
|
filterActive.value = true; // Activate filtering when typing in search
|
||||||
lastSearchQuery.value = event.target.value;
|
lastSearchQuery.value = event.target.value;
|
||||||
|
hasSearched.value = true; // Mark that a search has been performed
|
||||||
|
maintainFocusAfterRefresh.value = true; // Maintain focus after refresh
|
||||||
emit('update:modelValue', event.target.value);
|
emit('update:modelValue', event.target.value);
|
||||||
emit('search', event.target.value);
|
emit('search', event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFocus = (event) => {
|
const handleFocus = (event) => {
|
||||||
searchActive.value = true;
|
searchActive.value = true;
|
||||||
|
filterActive.value = true; // Activate filtering when focusing the search bar
|
||||||
|
maintainFocusAfterRefresh.value = true; // Maintain focus after refresh
|
||||||
|
|
||||||
// If there's a saved search, make sure it's applied
|
// If there's a saved search, make sure it's applied
|
||||||
if (props.modelValue) {
|
if (props.modelValue) {
|
||||||
inputValue.value = props.modelValue;
|
inputValue.value = props.modelValue;
|
||||||
|
|
||||||
|
// Force a re-evaluation of the filteredVMs computed property
|
||||||
|
nextTick(() => {
|
||||||
|
// This is a hack to force Vue to re-evaluate the computed property
|
||||||
|
const temp = filteredVMs.value.length;
|
||||||
|
console.log('Forcing filter application, filtered count:', temp);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
emit('focus', event);
|
emit('focus', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = (event) => {
|
const handleBlur = (event) => {
|
||||||
|
// Only deactivate filtering if no search has been performed
|
||||||
|
if (!hasSearched.value) {
|
||||||
|
filterActive.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the blur was caused by a click outside the component
|
||||||
|
const isClickOutside = !controlsBar.value?.contains(event.relatedTarget);
|
||||||
|
if (isClickOutside) {
|
||||||
|
maintainFocusAfterRefresh.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
emit('blur', event);
|
emit('blur', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -363,21 +397,27 @@ const toggleList = () => {
|
|||||||
|
|
||||||
// If we're opening the list (currently closed)
|
// If we're opening the list (currently closed)
|
||||||
if (!props.showList) {
|
if (!props.showList) {
|
||||||
// When opening the list, restore the last search query
|
// When opening the list via List VMs button, don't apply filtering initially
|
||||||
nextTick(() => {
|
// Only deactivate filtering if no search has been performed
|
||||||
if (lastSearchQuery.value) {
|
if (!hasSearched.value) {
|
||||||
inputValue.value = lastSearchQuery.value;
|
filterActive.value = false;
|
||||||
searchActive.value = true;
|
}
|
||||||
|
|
||||||
|
// But always restore the previous search text
|
||||||
|
if (lastSearchQuery.value) {
|
||||||
|
// Ensure the model value is preserved
|
||||||
|
if (props.modelValue !== lastSearchQuery.value) {
|
||||||
|
emit('update:modelValue', lastSearchQuery.value);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
// If we're closing the list (currently open)
|
// If we're closing the list (currently open)
|
||||||
else {
|
else {
|
||||||
// When closing, save the current search but don't clear it
|
// When closing, save the current search
|
||||||
if (props.modelValue) {
|
if (props.modelValue) {
|
||||||
lastSearchQuery.value = props.modelValue;
|
lastSearchQuery.value = props.modelValue;
|
||||||
|
// Don't clear the model value when closing
|
||||||
}
|
}
|
||||||
// Don't emit update:modelValue here to preserve the search
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('toggle-list');
|
emit('toggle-list');
|
||||||
@ -425,6 +465,17 @@ const handleClickOutside = (event) => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('click', handleClickOutside);
|
document.addEventListener('click', handleClickOutside);
|
||||||
|
|
||||||
|
// Add click handler for search input
|
||||||
|
const searchInput = document.querySelector('.search-input');
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.addEventListener('click', () => {
|
||||||
|
if (props.showList && props.modelValue) {
|
||||||
|
filterActive.value = true;
|
||||||
|
applyFilter();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@ -460,7 +511,13 @@ watch(() => props.showList, (isOpen) => {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (lastSearchQuery.value) {
|
if (lastSearchQuery.value) {
|
||||||
inputValue.value = lastSearchQuery.value;
|
inputValue.value = lastSearchQuery.value;
|
||||||
searchActive.value = true;
|
|
||||||
|
// If the user clicked on the search bar to open it, apply the filter
|
||||||
|
if (document.activeElement &&
|
||||||
|
document.activeElement.classList.contains('search-input')) {
|
||||||
|
filterActive.value = true;
|
||||||
|
applyFilter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -472,6 +529,8 @@ watch(() => props.showList, (isOpen) => {
|
|||||||
if (effectiveVM) {
|
if (effectiveVM) {
|
||||||
inputValue.value = effectiveVM;
|
inputValue.value = effectiveVM;
|
||||||
}
|
}
|
||||||
|
// Reset filter active state when closing
|
||||||
|
filterActive.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -481,6 +540,73 @@ watch([() => props.selectedVM, () => props.vmFromUrl], () => {
|
|||||||
scrollToSelectedVM();
|
scrollToSelectedVM();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add a method to explicitly apply the filter
|
||||||
|
const applyFilter = () => {
|
||||||
|
filterActive.value = true;
|
||||||
|
// Force computed property re-evaluation
|
||||||
|
nextTick(() => {
|
||||||
|
const temp = filteredVMs.value.length;
|
||||||
|
console.log('Filter applied, filtered count:', temp);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update the watch for props.vmList to maintain focus
|
||||||
|
watch(() => props.vmList, () => {
|
||||||
|
// When VM list refreshes, ensure search is preserved
|
||||||
|
if (props.showList && lastSearchQuery.value) {
|
||||||
|
// Make sure the model value is preserved
|
||||||
|
if (props.modelValue !== lastSearchQuery.value) {
|
||||||
|
emit('update:modelValue', lastSearchQuery.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a search has been performed, keep filtering active
|
||||||
|
if (hasSearched.value && props.modelValue) {
|
||||||
|
filterActive.value = true;
|
||||||
|
|
||||||
|
// If we should maintain focus, refocus the search input
|
||||||
|
if (maintainFocusAfterRefresh.value) {
|
||||||
|
nextTick(() => {
|
||||||
|
const searchInput = document.querySelector('.search-input');
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
applyFilter();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update handleSearchClick to set maintainFocusAfterRefresh
|
||||||
|
const handleSearchClick = () => {
|
||||||
|
if (props.showList) {
|
||||||
|
// When clicking the search input while list is open, always apply filtering
|
||||||
|
filterActive.value = true;
|
||||||
|
maintainFocusAfterRefresh.value = true; // Maintain focus after refresh
|
||||||
|
|
||||||
|
// If there's a saved search, make sure it's applied to the model
|
||||||
|
if (lastSearchQuery.value && !props.modelValue) {
|
||||||
|
emit('update:modelValue', lastSearchQuery.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force filter application
|
||||||
|
applyFilter();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add a method to force focus on the search input
|
||||||
|
const focusSearchInput = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
const searchInput = document.querySelector('.search-input');
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -173,6 +173,10 @@ const selectedVMData = computed(() => {
|
|||||||
const handleSearch = (value) => {
|
const handleSearch = (value) => {
|
||||||
searchQuery.value = value;
|
searchQuery.value = value;
|
||||||
searchActive.value = true;
|
searchActive.value = true;
|
||||||
|
// Store the search query in localStorage for persistence
|
||||||
|
if (value) {
|
||||||
|
localStorage.setItem('vmSearchQuery', value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle search focus
|
// Handle search focus
|
||||||
@ -211,12 +215,20 @@ const selectVM = (vm) => {
|
|||||||
const clearSearch = () => {
|
const clearSearch = () => {
|
||||||
searchQuery.value = '';
|
searchQuery.value = '';
|
||||||
searchActive.value = false;
|
searchActive.value = false;
|
||||||
|
localStorage.removeItem('vmSearchQuery');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lifecycle hooks
|
// Lifecycle hooks
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('VMOverview mounted, route.query.vm:', route.query.vm);
|
console.log('VMOverview mounted, route.query.vm:', route.query.vm);
|
||||||
const vmFromQuery = route.query.vm;
|
const vmFromQuery = route.query.vm;
|
||||||
|
|
||||||
|
// Restore previous search query from localStorage if available
|
||||||
|
const savedSearch = localStorage.getItem('vmSearchQuery');
|
||||||
|
if (savedSearch) {
|
||||||
|
searchQuery.value = savedSearch;
|
||||||
|
}
|
||||||
|
|
||||||
if (vmFromQuery) {
|
if (vmFromQuery) {
|
||||||
console.log('Setting selectedVM to:', vmFromQuery);
|
console.log('Setting selectedVM to:', vmFromQuery);
|
||||||
selectedVM.value = vmFromQuery;
|
selectedVM.value = vmFromQuery;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user