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
</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>
<input
type="text"
@@ -36,6 +37,21 @@
</button>
</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">
<button
class="btn btn-outline-secondary dropdown-toggle"
@@ -197,6 +213,11 @@ const isVMSelected = (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
onMounted(() => {
// Set up click outside handler
@@ -304,35 +325,68 @@ const handleBlur = (event) => {
// Handle click on search input
const handleSearchClick = () => {
if (props.showList) {
// When clicking the search input while list is open, activate filtering
// When clicking the search input, activate filtering mode
if (props.showList && !isFilterActive.value) {
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
const toggleList = () => {
emit('toggle-list');
// If the list is already open, toggle filtering instead of closing
if (props.showList) {
// If we're in list mode (not filtering) and the button is clicked, close the drawer
if (!isFilterActive.value) {
// Save the current search text before closing
if (props.modelValue) {
searchText.value = props.modelValue;
// Save to localStorage
localStorage.setItem('vmSearchText', props.modelValue);
}
// When toggling the list, ensure search text is preserved
const savedSearchText = localStorage.getItem('vmSearchText');
// Close the drawer
emit('toggle-list');
return;
}
if (!props.showList) {
// When opening the list, restore search text if available
if (savedSearchText && !inputValue.value) {
// 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(() => {
inputValue.value = savedSearchText;
searchText.value = savedSearchText;
emit('update:modelValue', savedSearchText);
scrollToSelectedVM();
});
}
// 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
@@ -372,23 +426,9 @@ const clearSearch = () => {
// Clear selected VM
const clearSelectedVM = () => {
// Clear the input value
inputValue.value = '';
// Clear from localStorage
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('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>
<style scoped>
@@ -976,4 +1036,66 @@ const loadFiltersFromLocalStorage = () => {
border-color: #0d6efd;
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>