From 94d0ed544fee08d5fe42ee6d1109176409b3e09e Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Sun, 2 Mar 2025 10:50:49 -0500 Subject: [PATCH] Reuse data to avoid dupe API calls --- .../src/components/pages/vms/VMOverview.vue | 73 ++++++++++++++----- pvc-vue/src/stores/cluster.js | 13 ++++ pvc-vue/src/stores/vm.js | 17 +++++ pvc-vue/src/views/VMs.vue | 4 +- 4 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 pvc-vue/src/stores/cluster.js create mode 100644 pvc-vue/src/stores/vm.js diff --git a/pvc-vue/src/components/pages/vms/VMOverview.vue b/pvc-vue/src/components/pages/vms/VMOverview.vue index 6da0941..b0bdd2e 100644 --- a/pvc-vue/src/components/pages/vms/VMOverview.vue +++ b/pvc-vue/src/components/pages/vms/VMOverview.vue @@ -191,7 +191,12 @@
- Please select a VM from the list to view its details + + Selected VM does not exist + + + Please select a VM from the list to view its details +
@@ -245,6 +250,9 @@ const sections = ref({ storage: true }); +// Add new state for tracking invalid VM selection +const invalidVMSelected = ref(false); + // Toggle VM list visibility const toggleVMList = () => { if (showVMList.value) { @@ -254,6 +262,7 @@ const toggleVMList = () => { showVMList.value = true; searchActive.value = false; + invalidVMSelected.value = false; // Scroll to selected VM after the list is shown if (selectedVM.value) { @@ -456,9 +465,19 @@ const filterVMs = () => { // Select a VM const selectVM = (vmName) => { - selectedVM.value = vmName; + const vmExists = props.vmData.some(vm => vm.name === vmName); + + if (vmExists) { + selectedVM.value = vmName; + invalidVMSelected.value = false; + showVMList.value = false; + } else { + selectedVM.value = ''; + invalidVMSelected.value = true; + showVMList.value = false; + } + router.push({ query: { vm: vmName } }); - showVMList.value = false; }; // Scroll to the selected VM in the list @@ -510,22 +529,32 @@ onMounted(() => { // Initialize with URL state if present const vmFromQuery = route.query.vm; - if (vmFromQuery && props.vmData.some(vm => vm.name === vmFromQuery)) { - selectVM(vmFromQuery); - showVMList.value = false; + if (vmFromQuery) { + // Check if we already have data + if (props.vmData.length) { + selectVM(vmFromQuery); + } else { + // If no data yet, set the VM but mark as pending verification + selectedVM.value = vmFromQuery; + showVMList.value = false; + // Don't set invalidVMSelected yet - wait for data + } } else if (props.vmData.length > 0) { showVMList.value = true; selectedVM.value = ''; + invalidVMSelected.value = false; } // Initialize filters with available states and nodes - availableStates.value.forEach(state => { - appliedFilters.value.states[state] = false; - }); - - availableNodes.value.forEach(node => { - appliedFilters.value.nodes[node] = false; - }); + if (props.vmData.length) { + availableStates.value.forEach(state => { + appliedFilters.value.states[state] = false; + }); + + availableNodes.value.forEach(node => { + appliedFilters.value.nodes[node] = false; + }); + } }); onUnmounted(() => { @@ -535,14 +564,12 @@ onUnmounted(() => { // Watch for route changes to update selected VM watch(() => route.query.vm, (newVm) => { - if (newVm && props.vmData.some(vm => vm.name === newVm)) { + if (newVm) { selectVM(newVm); - // Hide VM list when navigating directly to a VM - showVMList.value = false; } else if (props.vmData.length > 0) { - // If no VM specified in URL, show list and clear selection selectedVM.value = ''; showVMList.value = true; + invalidVMSelected.value = false; } }); @@ -556,9 +583,19 @@ watch(() => showVMList.value, (isVisible) => { } }); -// Add console logging to debug data flow +// Modify the vmData watcher to handle updates and maintain selection watch(() => props.vmData, (newData) => { console.log('VMOverview received vmData:', newData); + + // If we have a selected VM, verify it still exists in the new data + if (selectedVM.value) { + const vmStillExists = newData.some(vm => vm.name === selectedVM.value); + if (!vmStillExists) { + invalidVMSelected.value = true; + } else { + invalidVMSelected.value = false; + } + } }, { immediate: true }); // Helper functions diff --git a/pvc-vue/src/stores/cluster.js b/pvc-vue/src/stores/cluster.js new file mode 100644 index 0000000..e01562d --- /dev/null +++ b/pvc-vue/src/stores/cluster.js @@ -0,0 +1,13 @@ +import { defineStore } from 'pinia'; + +export const useClusterStore = defineStore('cluster', { + state: () => ({ + clusterData: {} + }), + + actions: { + setClusterData(data) { + this.clusterData = data; + } + } +}); \ No newline at end of file diff --git a/pvc-vue/src/stores/vm.js b/pvc-vue/src/stores/vm.js new file mode 100644 index 0000000..45a85d6 --- /dev/null +++ b/pvc-vue/src/stores/vm.js @@ -0,0 +1,17 @@ +import { defineStore } from 'pinia'; + +export const useVMStore = defineStore('vm', { + state: () => ({ + vmList: [], + metrics: {} + }), + + actions: { + setVMList(vms) { + this.vmList = vms; + }, + setMetrics(metrics) { + this.metrics = metrics; + } + } +}); \ No newline at end of file diff --git a/pvc-vue/src/views/VMs.vue b/pvc-vue/src/views/VMs.vue index c56cab9..4103fc6 100644 --- a/pvc-vue/src/views/VMs.vue +++ b/pvc-vue/src/views/VMs.vue @@ -13,6 +13,7 @@ import PageTitle from '../components/general/PageTitle.vue'; import VMOverview from '../components/pages/vms/VMOverview.vue'; +// Define props to receive data from App.vue const props = defineProps({ vmData: { type: Array, @@ -30,9 +31,6 @@ const props = defineProps({ default: () => ({}) } }); - -// Add debugging -console.log('VMs.vue received vmData:', props.vmData);