Compare commits
	
		
			2 Commits
		
	
	
		
			8d1028ab47
			...
			47b4e6e182
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					47b4e6e182 | ||
| 
						 | 
					acfd2554b0 | 
@@ -99,10 +99,10 @@
 | 
			
		||||
          :key="vm.name"
 | 
			
		||||
          :data-vm-name="vm.name"
 | 
			
		||||
          class="vm-list-item"
 | 
			
		||||
          :class="{ 'active': selectedVM === vm.name || vmFromUrl === vm.name }"
 | 
			
		||||
          :class="{ 'active': isVMSelected(vm.name) }"
 | 
			
		||||
          @click="handleVMSelect(vm)"
 | 
			
		||||
        >
 | 
			
		||||
          <div v-if="selectedVM === vm.name || vmFromUrl === vm.name" class="active-indicator"></div>
 | 
			
		||||
          <div v-if="isVMSelected(vm.name)" class="active-indicator"></div>
 | 
			
		||||
          <div class="vm-item-content">
 | 
			
		||||
            <div class="vm-name">{{ vm.name }}</div>
 | 
			
		||||
            <div class="vm-state" :class="getStateClass(vm.state)">
 | 
			
		||||
@@ -190,6 +190,13 @@ const shouldShowClearButton = computed(() => {
 | 
			
		||||
         (!props.showList && (props.selectedVM || localStorage.getItem('selectedVMId')));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Add a computed property to check if a VM is selected
 | 
			
		||||
const isVMSelected = (vmName) => {
 | 
			
		||||
  return props.selectedVM === vmName || 
 | 
			
		||||
         props.vmFromUrl === vmName || 
 | 
			
		||||
         localStorage.getItem('selectedVMId') === vmName;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Initialize the component
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  // Set up click outside handler
 | 
			
		||||
@@ -200,14 +207,8 @@ onMounted(() => {
 | 
			
		||||
  
 | 
			
		||||
  // Restore search text from localStorage if available
 | 
			
		||||
  const savedSearchText = localStorage.getItem('vmSearchText');
 | 
			
		||||
  if (savedSearchText) {
 | 
			
		||||
    searchText.value = savedSearchText;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Load saved filters
 | 
			
		||||
  loadFiltersFromLocalStorage();
 | 
			
		||||
  
 | 
			
		||||
  // Initialize input value based on selected VM
 | 
			
		||||
  // Initialize input value based on context
 | 
			
		||||
  if (!props.showList) {
 | 
			
		||||
    // If list is closed, show the selected VM name in the input
 | 
			
		||||
    const effectiveVM = props.selectedVM || props.vmFromUrl || savedVMId;
 | 
			
		||||
@@ -220,17 +221,33 @@ onMounted(() => {
 | 
			
		||||
        inputValue.value = effectiveVM;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if (props.showList && props.modelValue) {
 | 
			
		||||
    // If list is open and there's a search query, show that
 | 
			
		||||
    inputValue.value = props.modelValue;
 | 
			
		||||
    searchText.value = props.modelValue;
 | 
			
		||||
    // Save to localStorage
 | 
			
		||||
    localStorage.setItem('vmSearchText', props.modelValue);
 | 
			
		||||
  } else if (props.showList) {
 | 
			
		||||
    // If list is open
 | 
			
		||||
    if (props.modelValue) {
 | 
			
		||||
      // If there's a model value, use it
 | 
			
		||||
      inputValue.value = props.modelValue;
 | 
			
		||||
      searchText.value = props.modelValue;
 | 
			
		||||
    } else if (savedSearchText) {
 | 
			
		||||
      // If there's saved search text, restore it
 | 
			
		||||
      inputValue.value = savedSearchText;
 | 
			
		||||
      searchText.value = savedSearchText;
 | 
			
		||||
      emit('update:modelValue', savedSearchText);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Always restore the search text ref from localStorage
 | 
			
		||||
  if (savedSearchText) {
 | 
			
		||||
    searchText.value = savedSearchText;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Load saved filters
 | 
			
		||||
  loadFiltersFromLocalStorage();
 | 
			
		||||
  
 | 
			
		||||
  // If the list is visible on mount, scroll to selected VM
 | 
			
		||||
  if (props.showList && (props.selectedVM || props.vmFromUrl || savedVMId)) {
 | 
			
		||||
    scrollToSelectedVM();
 | 
			
		||||
  if (props.showList) {
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
      scrollToSelectedVM();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -242,14 +259,23 @@ onUnmounted(() => {
 | 
			
		||||
const handleSearch = (event) => {
 | 
			
		||||
  const value = event.target.value;
 | 
			
		||||
  inputValue.value = value;
 | 
			
		||||
  
 | 
			
		||||
  // Update search text ref
 | 
			
		||||
  searchText.value = value;
 | 
			
		||||
  isFilterActive.value = true;
 | 
			
		||||
  
 | 
			
		||||
  // Save search text to localStorage
 | 
			
		||||
  localStorage.setItem('vmSearchText', value);
 | 
			
		||||
  
 | 
			
		||||
  // Update the model
 | 
			
		||||
  emit('update:modelValue', value);
 | 
			
		||||
  emit('search', value);
 | 
			
		||||
  
 | 
			
		||||
  // Save to localStorage for search history
 | 
			
		||||
  if (value) {
 | 
			
		||||
    localStorage.setItem('vmSearchText', value);
 | 
			
		||||
  } else {
 | 
			
		||||
    localStorage.removeItem('vmSearchText');
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Update filter state
 | 
			
		||||
  isFilterActive.value = !!value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Handle focus on search input
 | 
			
		||||
@@ -292,60 +318,21 @@ const handleSearchClick = () => {
 | 
			
		||||
 | 
			
		||||
// Toggle the VM list
 | 
			
		||||
const toggleList = () => {
 | 
			
		||||
  // 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);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // 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) {
 | 
			
		||||
  emit('toggle-list');
 | 
			
		||||
  
 | 
			
		||||
  // When toggling the list, ensure search text is preserved
 | 
			
		||||
  const savedSearchText = localStorage.getItem('vmSearchText');
 | 
			
		||||
  
 | 
			
		||||
  if (!props.showList) {
 | 
			
		||||
    // When opening the list, restore search text if available
 | 
			
		||||
    if (savedSearchText && !inputValue.value) {
 | 
			
		||||
      nextTick(() => {
 | 
			
		||||
        scrollToSelectedVM();
 | 
			
		||||
        inputValue.value = savedSearchText;
 | 
			
		||||
        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
 | 
			
		||||
@@ -391,6 +378,14 @@ const clearSelectedVM = () => {
 | 
			
		||||
  // 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');
 | 
			
		||||
  
 | 
			
		||||
@@ -636,10 +631,12 @@ watch([() => props.selectedVM, () => props.vmFromUrl], ([selectedVM, vmFromUrl])
 | 
			
		||||
// Add a function to scroll to the selected VM
 | 
			
		||||
const scrollToSelectedVM = () => {
 | 
			
		||||
  nextTick(() => {
 | 
			
		||||
    // Find the first selected VM
 | 
			
		||||
    const selectedVMName = props.selectedVM || props.vmFromUrl || localStorage.getItem('selectedVMId');
 | 
			
		||||
    if (selectedVMName && vmListContainer.value) {
 | 
			
		||||
      const activeElement = vmListContainer.value.querySelector(`[data-vm-name="${selectedVMName}"]`);
 | 
			
		||||
      if (activeElement) {
 | 
			
		||||
        // Scroll the element into view
 | 
			
		||||
        activeElement.scrollIntoView({ block: 'center', behavior: 'smooth' });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -172,9 +172,15 @@ const selectedVMData = computed(() => {
 | 
			
		||||
const handleSearch = (value) => {
 | 
			
		||||
  searchQuery.value = value;
 | 
			
		||||
  searchActive.value = true;
 | 
			
		||||
  
 | 
			
		||||
  // Store the search query in localStorage for persistence
 | 
			
		||||
  if (value) {
 | 
			
		||||
    localStorage.setItem('vmSearchQuery', value);
 | 
			
		||||
    // Also save to vmSearchText for consistency
 | 
			
		||||
    localStorage.setItem('vmSearchText', value);
 | 
			
		||||
  } else {
 | 
			
		||||
    localStorage.removeItem('vmSearchQuery');
 | 
			
		||||
    // Don't remove vmSearchText here - it's used for search history
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -195,9 +201,17 @@ const handleSearchBlur = (event) => {
 | 
			
		||||
// Toggle VM list visibility
 | 
			
		||||
const toggleVMList = () => {
 | 
			
		||||
  showVMList.value = !showVMList.value;
 | 
			
		||||
  
 | 
			
		||||
  if (showVMList.value) {
 | 
			
		||||
    // When opening the list
 | 
			
		||||
    searchActive.value = false;
 | 
			
		||||
    invalidVMSelected.value = false;
 | 
			
		||||
    
 | 
			
		||||
    // Restore search text if available
 | 
			
		||||
    const savedSearchText = localStorage.getItem('vmSearchText');
 | 
			
		||||
    if (savedSearchText && !searchQuery.value) {
 | 
			
		||||
      searchQuery.value = savedSearchText;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -231,12 +245,22 @@ const clearSelectedVM = () => {
 | 
			
		||||
  selectedVM.value = '';
 | 
			
		||||
  invalidVMSelected.value = false;
 | 
			
		||||
  
 | 
			
		||||
  // Clear the search query in this component
 | 
			
		||||
  searchQuery.value = '';
 | 
			
		||||
  
 | 
			
		||||
  // Show the VM list
 | 
			
		||||
  showVMList.value = true;
 | 
			
		||||
  
 | 
			
		||||
  // Clear from localStorage
 | 
			
		||||
  // Clear VM selection from localStorage
 | 
			
		||||
  localStorage.removeItem('selectedVMId');
 | 
			
		||||
  
 | 
			
		||||
  // Don't clear vmSearchText unless it matches the VM name
 | 
			
		||||
  const savedVMId = localStorage.getItem('selectedVMId');
 | 
			
		||||
  const savedSearchText = localStorage.getItem('vmSearchText');
 | 
			
		||||
  if (savedSearchText === savedVMId) {
 | 
			
		||||
    localStorage.removeItem('vmSearchText');
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Clear URL parameter if it exists
 | 
			
		||||
  if (route.query.vm) {
 | 
			
		||||
    router.replace({ path: '/vms' }, { replace: true });
 | 
			
		||||
@@ -254,29 +278,13 @@ onMounted(() => {
 | 
			
		||||
  const savedVMId = localStorage.getItem('selectedVMId');
 | 
			
		||||
  const vmFromQuery = route.query.vm;
 | 
			
		||||
  
 | 
			
		||||
  // Restore previous search query from localStorage if available
 | 
			
		||||
  // Restore previous search query from localStorage
 | 
			
		||||
  const savedSearch = localStorage.getItem('vmSearchQuery');
 | 
			
		||||
  if (savedSearch) {
 | 
			
		||||
    searchQuery.value = savedSearch;
 | 
			
		||||
  }
 | 
			
		||||
  const savedSearchText = localStorage.getItem('vmSearchText');
 | 
			
		||||
  
 | 
			
		||||
  let vmToSelect = null;
 | 
			
		||||
  // If we have a VM to select
 | 
			
		||||
  let vmToSelect = savedVMId || vmFromQuery;
 | 
			
		||||
  
 | 
			
		||||
  // Determine which VM to select
 | 
			
		||||
  if (savedVMId) {
 | 
			
		||||
    console.log('VM from localStorage:', savedVMId);
 | 
			
		||||
    vmToSelect = savedVMId;
 | 
			
		||||
  } else if (vmFromQuery) {
 | 
			
		||||
    console.log('VM from URL query:', vmFromQuery);
 | 
			
		||||
    vmToSelect = vmFromQuery;
 | 
			
		||||
    // Save to localStorage for persistence
 | 
			
		||||
    localStorage.setItem('selectedVMId', vmFromQuery);
 | 
			
		||||
    
 | 
			
		||||
    // Remove the VM ID from the URL without reloading the page
 | 
			
		||||
    router.replace({ path: '/vms' }, { replace: true });
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // If we have a VM to select and data is available
 | 
			
		||||
  if (vmToSelect && props.vmData.length > 0) {
 | 
			
		||||
    // Check if the VM exists
 | 
			
		||||
    const vmExists = props.vmData.some(v => v.name === vmToSelect);
 | 
			
		||||
@@ -287,14 +295,40 @@ onMounted(() => {
 | 
			
		||||
      
 | 
			
		||||
      // Set the search query to the VM name for display in the search bar
 | 
			
		||||
      searchQuery.value = vmToSelect;
 | 
			
		||||
      
 | 
			
		||||
      // If from URL, save to localStorage for persistence
 | 
			
		||||
      if (vmFromQuery && !savedVMId) {
 | 
			
		||||
        localStorage.setItem('selectedVMId', vmFromQuery);
 | 
			
		||||
        
 | 
			
		||||
        // Remove the VM ID from the URL without reloading the page
 | 
			
		||||
        router.replace({ path: '/vms' }, { replace: true });
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      console.log('Selected VM does not exist:', vmToSelect);
 | 
			
		||||
      invalidVMSelected.value = true;
 | 
			
		||||
      localStorage.removeItem('selectedVMId');
 | 
			
		||||
      
 | 
			
		||||
      // Only clear search text if it matches the VM name
 | 
			
		||||
      if (savedSearchText === vmToSelect) {
 | 
			
		||||
        localStorage.removeItem('vmSearchText');
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Show the VM list with any saved search
 | 
			
		||||
      showVMList.value = true;
 | 
			
		||||
      if (savedSearch) {
 | 
			
		||||
        searchQuery.value = savedSearch;
 | 
			
		||||
      } else if (savedSearchText) {
 | 
			
		||||
        searchQuery.value = savedSearchText;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if (!vmToSelect && props.vmData.length > 0) {
 | 
			
		||||
    // No VM selected, show the list
 | 
			
		||||
  } else {
 | 
			
		||||
    // No VM selected, show the list with any saved search
 | 
			
		||||
    showVMList.value = true;
 | 
			
		||||
    if (savedSearch) {
 | 
			
		||||
      searchQuery.value = savedSearch;
 | 
			
		||||
    } else if (savedSearchText) {
 | 
			
		||||
      searchQuery.value = savedSearchText;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  isLoading.value = false;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user