Jump to current VM in full VM list

This commit is contained in:
Joshua Boniface 2025-03-01 14:34:50 -05:00
parent dbb1dae0d9
commit 41d9ef4057

View File

@ -98,6 +98,7 @@
class="vm-list-item" class="vm-list-item"
:class="{ 'active': selectedVM === vm.name }" :class="{ 'active': selectedVM === vm.name }"
@click="selectVM(vm.name)" @click="selectVM(vm.name)"
:ref="el => { if (vm.name === selectedVM) selectedVMRef = el; }"
> >
<div class="vm-item-content"> <div class="vm-item-content">
<div class="vm-name">{{ vm.name }}</div> <div class="vm-name">{{ vm.name }}</div>
@ -248,7 +249,7 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'; import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import PageTitle from '../components/PageTitle.vue'; import PageTitle from '../components/PageTitle.vue';
import { useApiStore } from '../stores/api'; import { useApiStore } from '../stores/api';
@ -268,6 +269,7 @@ const appliedFilters = ref({
states: {}, states: {},
nodes: {} nodes: {}
}); });
const selectedVMRef = ref(null);
// Section visibility state // Section visibility state
const sections = ref({ const sections = ref({
@ -286,6 +288,13 @@ const toggleVMList = () => {
showVMList.value = true; showVMList.value = true;
searchActive.value = false; searchActive.value = false;
// Scroll to selected VM after the list is shown
if (selectedVM.value) {
nextTick(() => {
scrollToSelectedVM();
});
}
}; };
// Toggle filter menu // Toggle filter menu
@ -515,6 +524,12 @@ const handleSearchFocus = () => {
// Show VM list when search is focused // Show VM list when search is focused
if (!showVMList.value) { if (!showVMList.value) {
showVMList.value = true; showVMList.value = true;
// Scroll to selected VM after the list is shown
if (selectedVM.value) {
nextTick(() => {
scrollToSelectedVM();
});
}
} }
searchActive.value = true; searchActive.value = true;
}; };
@ -553,6 +568,25 @@ const selectVM = (vmName) => {
showVMList.value = false; showVMList.value = false;
}; };
// Scroll to the selected VM in the list
const scrollToSelectedVM = () => {
if (selectedVMRef.value) {
// Get the VM list container
const vmList = document.querySelector('.vm-list');
if (!vmList) return;
// Calculate the scroll position
const vmElement = selectedVMRef.value;
const vmPosition = vmElement.offsetTop;
const listHeight = vmList.clientHeight;
const vmHeight = vmElement.clientHeight;
// Scroll to position the selected VM in the middle of the list if possible
const scrollPosition = vmPosition - (listHeight / 2) + (vmHeight / 2);
vmList.scrollTop = Math.max(0, scrollPosition);
}
};
onMounted(() => { onMounted(() => {
fetchVMData(); fetchVMData();
}); });
@ -569,12 +603,21 @@ watch(() => route.query.vm, (newVm) => {
showVMList.value = true; showVMList.value = true;
} }
}); });
// Watch for changes in the VM list visibility
watch(() => showVMList.value, (isVisible) => {
if (isVisible && selectedVM.value) {
// Scroll to selected VM when the list becomes visible
nextTick(() => {
scrollToSelectedVM();
});
}
});
</script> </script>
<style scoped> <style scoped>
/* VM Controls Styles */ /* VM Controls */
.vm-controls-container { .vm-controls-container {
margin-bottom: 0.5rem;
background-color: white; background-color: white;
border: 1px solid rgba(0, 0, 0, 0.125); border: 1px solid rgba(0, 0, 0, 0.125);
border-radius: 0.25rem; border-radius: 0.25rem;
@ -755,12 +798,15 @@ watch(() => route.query.vm, (newVm) => {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-height: calc(100vh - 200px);
} }
.vm-list { .vm-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
overflow-y: auto;
max-height: calc(100vh - 200px);
} }
.vm-list-item { .vm-list-item {