First try at refactoring again

This commit is contained in:
Joshua Boniface
2025-03-02 19:05:24 -05:00
parent 47b4e6e182
commit b891929956

View File

@@ -13,7 +13,8 @@
<i class="fas fa-list"></i> List VMs <i class="fas fa-list"></i> List VMs
</button> </button>
<div class="search-box"> <!-- Search box - visible when drawer is open -->
<div v-if="showList" class="search-box">
<i class="fas fa-search search-icon"></i> <i class="fas fa-search search-icon"></i>
<input <input
type="text" type="text"
@@ -36,6 +37,21 @@
</button> </button>
</div> </div>
<!-- VM Display - visible when drawer is closed -->
<div v-else class="vm-display" @click="openSearchDrawer">
<button
v-if="selectedVMName"
class="vm-clear-btn"
@click.stop="clearSelectedVM"
title="Clear selected VM"
>
<i class="fas fa-times"></i>
</button>
<i class="fas fa-desktop vm-icon"></i>
<span class="vm-name">{{ selectedVMName || 'Select a VM...' }}</span>
<i class="fas fa-search search-icon-right"></i>
</div>
<div class="filter-dropdown" ref="filterDropdown"> <div class="filter-dropdown" ref="filterDropdown">
<button <button
class="btn btn-outline-secondary dropdown-toggle" class="btn btn-outline-secondary dropdown-toggle"
@@ -197,6 +213,11 @@ const isVMSelected = (vmName) => {
localStorage.getItem('selectedVMId') === vmName; localStorage.getItem('selectedVMId') === vmName;
}; };
// Computed property for the selected VM name
const selectedVMName = computed(() => {
return props.selectedVM || props.vmFromUrl || localStorage.getItem('selectedVMId') || '';
});
// Initialize the component // Initialize the component
onMounted(() => { onMounted(() => {
// Set up click outside handler // Set up click outside handler
@@ -304,35 +325,68 @@ const handleBlur = (event) => {
// Handle click on search input // Handle click on search input
const handleSearchClick = () => { const handleSearchClick = () => {
if (props.showList) { // When clicking the search input, activate filtering mode
// When clicking the search input while list is open, activate filtering if (props.showList && !isFilterActive.value) {
isFilterActive.value = true; isFilterActive.value = true;
// Restore search text if available
if (searchText.value && searchText.value !== inputValue.value) {
inputValue.value = searchText.value;
emit('update:modelValue', searchText.value);
}
} }
}; };
// Toggle the VM list // Toggle the VM list
const toggleList = () => { const toggleList = () => {
emit('toggle-list'); // If the list is already open, toggle filtering instead of closing
if (props.showList) {
// When toggling the list, ensure search text is preserved // If we're in list mode (not filtering) and the button is clicked, close the drawer
const savedSearchText = localStorage.getItem('vmSearchText'); if (!isFilterActive.value) {
// Save the current search text before closing
if (!props.showList) { if (props.modelValue) {
// When opening the list, restore search text if available searchText.value = props.modelValue;
if (savedSearchText && !inputValue.value) { // Save to localStorage
localStorage.setItem('vmSearchText', props.modelValue);
}
// Close the drawer
emit('toggle-list');
return;
}
// Toggle filtering mode
isFilterActive.value = !isFilterActive.value;
// If we're turning filtering on, make sure the search text is applied
if (isFilterActive.value && searchText.value) {
inputValue.value = searchText.value;
emit('update:modelValue', searchText.value);
}
// If we're turning filtering off (switching to list mode), scroll to selected VM
if (!isFilterActive.value) {
nextTick(() => { nextTick(() => {
inputValue.value = savedSearchText; scrollToSelectedVM();
searchText.value = savedSearchText;
emit('update:modelValue', savedSearchText);
}); });
} }
// No need to emit toggle-list since we're not closing the list
return;
} }
// If the list is closed, open it without filtering
if (!props.showList) {
// If we're opening the list, deactivate filtering
isFilterActive.value = false;
// Restore search text in the input, but don't apply filtering
if (searchText.value) {
inputValue.value = searchText.value;
emit('update:modelValue', searchText.value);
}
// Schedule scrolling to selected VM after the list opens
nextTick(() => {
scrollToSelectedVM();
});
}
emit('toggle-list');
}; };
// Handle clear button click // Handle clear button click
@@ -372,23 +426,9 @@ const clearSearch = () => {
// Clear selected VM // Clear selected VM
const clearSelectedVM = () => { const clearSelectedVM = () => {
// Clear the input value
inputValue.value = '';
// Clear from localStorage // Clear from localStorage
localStorage.removeItem('selectedVMId'); localStorage.removeItem('selectedVMId');
// Don't clear vmSearchText - that's for search history
// Only clear if the input value matches the selected VM
const savedVMId = localStorage.getItem('selectedVMId');
const savedSearchText = localStorage.getItem('vmSearchText');
if (savedSearchText === savedVMId) {
localStorage.removeItem('vmSearchText');
}
// Show the VM list
emit('toggle-list');
// Emit event to parent component // Emit event to parent component
emit('clear-vm'); emit('clear-vm');
}; };
@@ -663,6 +703,26 @@ const loadFiltersFromLocalStorage = () => {
} }
} }
}; };
// Method to open the search drawer
const openSearchDrawer = () => {
// Only open if it's not already open
if (!props.showList) {
// Set filter active to true to indicate we're in search mode
isFilterActive.value = true;
// Emit toggle-list to open the drawer
emit('toggle-list');
// Focus the search input after the drawer opens
nextTick(() => {
const searchInput = document.querySelector('.search-input');
if (searchInput) {
searchInput.focus();
}
});
}
};
</script> </script>
<style scoped> <style scoped>
@@ -976,4 +1036,66 @@ const loadFiltersFromLocalStorage = () => {
border-color: #0d6efd; border-color: #0d6efd;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
} }
/* Add these styles for the VM display */
.vm-display {
position: relative;
flex: 1;
min-width: 200px;
height: 38px;
padding: 0.375rem 0.75rem;
padding-left: 40px;
padding-right: 30px;
background-color: #f8f9fa;
border: 1px solid #ced4da;
border-radius: 0.25rem;
display: flex;
align-items: center;
cursor: pointer;
transition: background-color 0.2s;
}
.vm-display:hover {
background-color: #e9ecef;
}
.vm-clear-btn {
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: #6c757d;
cursor: pointer;
padding: 0;
font-size: 0.875rem;
transition: color 0.2s;
z-index: 5;
}
.vm-clear-btn:hover {
color: #dc3545;
}
.vm-icon {
color: #6c757d;
margin-right: 0.5rem;
}
.vm-name {
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
.search-icon-right {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: #6c757d;
}
</style> </style>