Unify and clean up position styling
This commit is contained in:
		| @@ -44,8 +44,7 @@ const selectNode = (node) => { | ||||
|   gap: 0.5rem; | ||||
|   background-color: white; | ||||
|   border-radius: 0.25rem; | ||||
|   padding-top: 0.5rem; | ||||
|   margin-top: -1.25rem !important; | ||||
|   padding-top: 0.25rem; | ||||
|   border-bottom: 1px solid rgba(0, 0, 0, 0.125); | ||||
| } | ||||
|  | ||||
| @@ -75,5 +74,7 @@ const selectNode = (node) => { | ||||
| .node-tab.active { | ||||
|   color: #0d6efd; | ||||
|   background-color: rgba(13, 110, 253, 0.1); | ||||
|   border-bottom: 4px solid rgba(13, 110, 253, 0.25); | ||||
|   margin-bottom: -4px; | ||||
| } | ||||
| </style>  | ||||
| @@ -21,7 +21,6 @@ defineProps({ | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   margin-bottom: 1rem; | ||||
|   padding-bottom: 0.5rem; | ||||
|   border-bottom: 1px solid rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|   | ||||
| @@ -618,8 +618,7 @@ const loadFiltersFromLocalStorage = () => { | ||||
|   gap: 0.5rem; | ||||
|   background-color: white; | ||||
|   border-radius: 0.25rem; | ||||
|   padding-top: 0.5rem; | ||||
|   margin-top: -1.25rem !important; | ||||
|   padding-top: 0.25rem; | ||||
|   border-bottom: 1px solid rgba(0, 0, 0, 0.125); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,165 +1,163 @@ | ||||
| <template> | ||||
|   <div class="overview-container"> | ||||
|     <NodeSelectBar | ||||
|       v-model="selectedNode" | ||||
|       :nodes="availableNodes" | ||||
|       @select="handleNodeSelect" | ||||
|     /> | ||||
|   <NodeSelectBar | ||||
|     v-model="selectedNode" | ||||
|     :nodes="availableNodes" | ||||
|     @select="handleNodeSelect" | ||||
|   /> | ||||
|  | ||||
|     <!-- Node Details --> | ||||
|     <div v-if="selectedNodeData" class="node-details"> | ||||
|       <!-- Information Cards Section --> | ||||
|       <CollapsibleSection title="Node Information" :initially-expanded="sections.info"> | ||||
|         <div class="info-row"> | ||||
|           <!-- Card 1: Daemon State --> | ||||
|           <ValueCard | ||||
|             title="Daemon State" | ||||
|             :value="selectedNodeData.daemon_state || 'Unknown'" | ||||
|             :bg-color="getDaemonStateColor(selectedNodeData.daemon_state)" | ||||
|           /> | ||||
|   <!-- Node Details --> | ||||
|   <div v-if="selectedNodeData" class="content-container"> | ||||
|     <!-- Information Cards Section --> | ||||
|     <CollapsibleSection title="Node Information" :initially-expanded="sections.info"> | ||||
|       <div class="info-row"> | ||||
|         <!-- Card 1: Daemon State --> | ||||
|         <ValueCard | ||||
|           title="Daemon State" | ||||
|           :value="selectedNodeData.daemon_state || 'Unknown'" | ||||
|           :bg-color="getDaemonStateColor(selectedNodeData.daemon_state)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 2: Coordinator State --> | ||||
|           <ValueCard | ||||
|             title="Coordinator State" | ||||
|             :value="selectedNodeData.coordinator_state || 'Unknown'" | ||||
|             :bg-color="getCoordinatorStateColor(selectedNodeData.coordinator_state)" | ||||
|           /> | ||||
|         <!-- Card 2: Coordinator State --> | ||||
|         <ValueCard | ||||
|           title="Coordinator State" | ||||
|           :value="selectedNodeData.coordinator_state || 'Unknown'" | ||||
|           :bg-color="getCoordinatorStateColor(selectedNodeData.coordinator_state)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 3: Domain State --> | ||||
|           <ValueCard | ||||
|             title="Domain State" | ||||
|             :value="selectedNodeData.domain_state || 'Unknown'" | ||||
|             :bg-color="getDomainStateColor(selectedNodeData.domain_state)" | ||||
|           /> | ||||
|         <!-- Card 3: Domain State --> | ||||
|         <ValueCard | ||||
|           title="Domain State" | ||||
|           :value="selectedNodeData.domain_state || 'Unknown'" | ||||
|           :bg-color="getDomainStateColor(selectedNodeData.domain_state)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 4: PVC Version --> | ||||
|           <ValueCard | ||||
|             title="PVC Version" | ||||
|             :value="selectedNodeData.pvc_version || 'Unknown'" | ||||
|           /> | ||||
|         <!-- Card 4: PVC Version --> | ||||
|         <ValueCard | ||||
|           title="PVC Version" | ||||
|           :value="selectedNodeData.pvc_version || 'Unknown'" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 5: Kernel Version --> | ||||
|           <ValueCard | ||||
|             title="Kernel Version" | ||||
|             :value="selectedNodeData.kernel || 'Unknown'" | ||||
|           /> | ||||
|         <!-- Card 5: Kernel Version --> | ||||
|         <ValueCard | ||||
|           title="Kernel Version" | ||||
|           :value="selectedNodeData.kernel || 'Unknown'" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 6: VM Count --> | ||||
|           <ValueCard | ||||
|             title="VM Count" | ||||
|             :value="selectedNodeData.domains_count || 0" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|         <!-- Card 6: VM Count --> | ||||
|         <ValueCard | ||||
|           title="VM Count" | ||||
|           :value="selectedNodeData.domains_count || 0" | ||||
|         /> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|       <!-- Utilization Graphs Section --> | ||||
|       <CollapsibleSection title="Health & Utilization Graphs" :initially-expanded="sections.graphs"> | ||||
|         <div class="graphs-row"> | ||||
|           <!-- Health Chart --> | ||||
|           <HealthChart | ||||
|             title="Node Health" | ||||
|             :value="selectedNodeData.health || 0" | ||||
|             :chart-data="nodeHealthChartData" | ||||
|             :maintenance="isMaintenanceMode" | ||||
|           /> | ||||
|     <!-- Utilization Graphs Section --> | ||||
|     <CollapsibleSection title="Health & Utilization Graphs" :initially-expanded="sections.graphs"> | ||||
|       <div class="graphs-row"> | ||||
|         <!-- Health Chart --> | ||||
|         <HealthChart | ||||
|           title="Node Health" | ||||
|           :value="selectedNodeData.health || 0" | ||||
|           :chart-data="nodeHealthChartData" | ||||
|           :maintenance="isMaintenanceMode" | ||||
|         /> | ||||
|  | ||||
|           <!-- CPU Utilization Chart --> | ||||
|           <CPUChart | ||||
|             title="CPU Utilization" | ||||
|             :value="calculateCpuUtilization(selectedNodeData)" | ||||
|             :chart-data="nodeCpuChartData" | ||||
|           /> | ||||
|         <!-- CPU Utilization Chart --> | ||||
|         <CPUChart | ||||
|           title="CPU Utilization" | ||||
|           :value="calculateCpuUtilization(selectedNodeData)" | ||||
|           :chart-data="nodeCpuChartData" | ||||
|         /> | ||||
|  | ||||
|           <!-- Memory Utilization Chart --> | ||||
|           <MemoryChart | ||||
|             title="Memory Utilization" | ||||
|             :value="calculateMemoryUtilization(selectedNodeData)" | ||||
|             :chart-data="nodeMemoryChartData" | ||||
|           /> | ||||
|         <!-- Memory Utilization Chart --> | ||||
|         <MemoryChart | ||||
|           title="Memory Utilization" | ||||
|           :value="calculateMemoryUtilization(selectedNodeData)" | ||||
|           :chart-data="nodeMemoryChartData" | ||||
|         /> | ||||
|  | ||||
|           <!-- Allocated Memory Chart --> | ||||
|           <StorageChart | ||||
|             title="Allocated Memory" | ||||
|             :value="calculateAllocatedMemory(selectedNodeData)" | ||||
|             :chart-data="nodeAllocatedMemoryChartData" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|         <!-- Allocated Memory Chart --> | ||||
|         <StorageChart | ||||
|           title="Allocated Memory" | ||||
|           :value="calculateAllocatedMemory(selectedNodeData)" | ||||
|           :chart-data="nodeAllocatedMemoryChartData" | ||||
|         /> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|       <!-- CPU Resources Section --> | ||||
|       <CollapsibleSection title="CPU Resources" :initially-expanded="sections.cpu"> | ||||
|         <div class="resources-row-cpu"> | ||||
|           <!-- Card 1: Host CPUs --> | ||||
|           <ValueCard | ||||
|             title="Host CPUs" | ||||
|             :value="selectedNodeData.cpu_count || 0" | ||||
|           /> | ||||
|     <!-- CPU Resources Section --> | ||||
|     <CollapsibleSection title="CPU Resources" :initially-expanded="sections.cpu"> | ||||
|       <div class="resources-row-cpu"> | ||||
|         <!-- Card 1: Host CPUs --> | ||||
|         <ValueCard | ||||
|           title="Host CPUs" | ||||
|           :value="selectedNodeData.cpu_count || 0" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 2: Guest CPUs --> | ||||
|           <ValueCard | ||||
|             title="Guest CPUs" | ||||
|             :value="selectedNodeData.vcpu?.allocated || 0" | ||||
|           /> | ||||
|         <!-- Card 2: Guest CPUs --> | ||||
|         <ValueCard | ||||
|           title="Guest CPUs" | ||||
|           :value="selectedNodeData.vcpu?.allocated || 0" | ||||
|         /> | ||||
|  | ||||
|           <!-- Card 3: Load --> | ||||
|           <ValueCard | ||||
|             title="Load" | ||||
|             :value="selectedNodeData.load || 0" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|         <!-- Card 3: Load --> | ||||
|         <ValueCard | ||||
|           title="Load" | ||||
|           :value="selectedNodeData.load || 0" | ||||
|         /> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|       <!-- Memory Resources Section --> | ||||
|       <CollapsibleSection title="Memory Resources" :initially-expanded="sections.resources"> | ||||
|         <div class="resources-row-memory"> | ||||
|           <!-- Total Memory --> | ||||
|           <ValueCard | ||||
|             title="Total Memory" | ||||
|             :value="formatMemory(selectedNodeData.memory?.total)" | ||||
|           /> | ||||
|     <!-- Memory Resources Section --> | ||||
|     <CollapsibleSection title="Memory Resources" :initially-expanded="sections.resources"> | ||||
|       <div class="resources-row-memory"> | ||||
|         <!-- Total Memory --> | ||||
|         <ValueCard | ||||
|           title="Total Memory" | ||||
|           :value="formatMemory(selectedNodeData.memory?.total)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Used Memory --> | ||||
|           <ValueCard | ||||
|             title="Used Memory" | ||||
|             :value="formatMemory(selectedNodeData.memory?.used)" | ||||
|           /> | ||||
|         <!-- Used Memory --> | ||||
|         <ValueCard | ||||
|           title="Used Memory" | ||||
|           :value="formatMemory(selectedNodeData.memory?.used)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Free Memory --> | ||||
|           <ValueCard | ||||
|             title="Free Memory" | ||||
|             :value="formatMemory(selectedNodeData.memory?.free)" | ||||
|           /> | ||||
|         <!-- Free Memory --> | ||||
|         <ValueCard | ||||
|           title="Free Memory" | ||||
|           :value="formatMemory(selectedNodeData.memory?.free)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Allocated Memory --> | ||||
|           <ValueCard | ||||
|             title="Allocated Memory" | ||||
|             :value="formatMemory(selectedNodeData.memory?.allocated)" | ||||
|           /> | ||||
|         <!-- Allocated Memory --> | ||||
|         <ValueCard | ||||
|           title="Allocated Memory" | ||||
|           :value="formatMemory(selectedNodeData.memory?.allocated)" | ||||
|         /> | ||||
|  | ||||
|           <!-- Provisioned Memory --> | ||||
|           <ValueCard | ||||
|             title="Provisioned Memory" | ||||
|             :value="formatMemory(selectedNodeData.memory?.provisioned)" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|         <!-- Provisioned Memory --> | ||||
|         <ValueCard | ||||
|           title="Provisioned Memory" | ||||
|           :value="formatMemory(selectedNodeData.memory?.provisioned)" | ||||
|         /> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|       <!-- Running VMs Section --> | ||||
|       <CollapsibleSection title="Running VMs" :initially-expanded="sections.vms"> | ||||
|         <div class="vm-list-row"> | ||||
|           <NodeVMList  | ||||
|             :vmData="props.vmData" | ||||
|             :nodeData="props.nodeData" | ||||
|             :nodeName="selectedNode" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|     </div> | ||||
|     <!-- Running VMs Section --> | ||||
|     <CollapsibleSection title="Running VMs" :initially-expanded="sections.vms"> | ||||
|       <div class="vm-list-row"> | ||||
|         <NodeVMList  | ||||
|           :vmData="props.vmData" | ||||
|           :nodeData="props.nodeData" | ||||
|           :nodeName="selectedNode" | ||||
|         /> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|   </div> | ||||
|  | ||||
|     <!-- No node selected message --> | ||||
|     <div v-else class="no-node-selected"> | ||||
|       <p>Select a node to view details</p> | ||||
|     </div> | ||||
|   <!-- No node selected message --> | ||||
|   <div v-else class="no-node-selected"> | ||||
|     <p>Select a node to view details</p> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @@ -457,17 +455,11 @@ const handleNodeSelect = (node) => { | ||||
|  | ||||
| <style scoped> | ||||
| /* Add these missing styles from the original Nodes.vue */ | ||||
| .overview-container { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 0.5rem; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .content-container { | ||||
|   background-color: white; | ||||
|   border-radius: 0.25rem; | ||||
|   padding: 1rem; | ||||
|   width: 100%; | ||||
|   padding-top: 0.25rem; | ||||
| } | ||||
|  | ||||
| .loading-container { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <div class="overview-container"> | ||||
|   <div class="content-container"> | ||||
|     <!-- Information Cards Section --> | ||||
|     <CollapsibleSection title="Cluster Information" :initially-expanded="sections.info"> | ||||
|       <div class="metrics-row"> | ||||
| @@ -870,11 +870,12 @@ const isMaintenanceMode = computed(() => { | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .overview-container { | ||||
| .content-container { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 0.5rem; | ||||
|   width: 100%; | ||||
|   padding-top: 0.25rem; | ||||
| } | ||||
|  | ||||
| .metrics-row { | ||||
|   | ||||
| @@ -1,117 +1,115 @@ | ||||
| <template> | ||||
|   <div class="overview-container"> | ||||
|     <VMSearchBar | ||||
|       :key="`vm-search-${selectedVM}`" | ||||
|       v-model="searchQuery" | ||||
|       :selected-vm="selectedVM" | ||||
|       :vm-from-url="route.query.vm" | ||||
|       :show-list="showVMList" | ||||
|       :show-clear-button="true" | ||||
|       :vm-list="props.vmData" | ||||
|       @search="handleSearch" | ||||
|       @focus="handleSearchFocus" | ||||
|       @blur="handleSearchBlur" | ||||
|       @clear="clearSearch" | ||||
|       @toggle-list="toggleVMList" | ||||
|       @select-vm="selectVM" | ||||
|     /> | ||||
|   <VMSearchBar | ||||
|     :key="`vm-search-${selectedVM}`" | ||||
|     v-model="searchQuery" | ||||
|     :selected-vm="selectedVM" | ||||
|     :vm-from-url="route.query.vm" | ||||
|     :show-list="showVMList" | ||||
|     :show-clear-button="true" | ||||
|     :vm-list="props.vmData" | ||||
|     @search="handleSearch" | ||||
|     @focus="handleSearchFocus" | ||||
|     @blur="handleSearchBlur" | ||||
|     @clear="clearSearch" | ||||
|     @toggle-list="toggleVMList" | ||||
|     @select-vm="selectVM" | ||||
|   /> | ||||
|  | ||||
|     <!-- VM Details --> | ||||
|     <div v-if="selectedVMData && !showVMList" class="content-container"> | ||||
|       <CollapsibleSection title="VM Information" :initially-expanded="sections.info"> | ||||
|         <div class="info-grid-general"> | ||||
|           <ValueCard  | ||||
|             title="State"  | ||||
|             :value="selectedVMData.state || 'Unknown'" | ||||
|             :status="getStateColor(selectedVMData.state)" | ||||
|           /> | ||||
|           <ValueCard  | ||||
|             title="Node"  | ||||
|             :value="selectedVMData.node || 'N/A'" | ||||
|           /> | ||||
|           <ValueCard  | ||||
|             title="CPUs"  | ||||
|             :value="selectedVMData.vcpus || 0" | ||||
|           /> | ||||
|           <ValueCard  | ||||
|             title="Memory"  | ||||
|             :value="formatMemory(selectedVMData.memory)" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|  | ||||
|       <!-- Resources Section --> | ||||
|       <CollapsibleSection title="Resources" :initially-expanded="sections.resources"> | ||||
|         <div class="info-grid-resources"> | ||||
|           <ValueCard  | ||||
|             title="Disk Size"  | ||||
|             :value="formatStorage(selectedVMData.disk_size)" | ||||
|           /> | ||||
|           <ValueCard  | ||||
|             title="Network IPs"  | ||||
|             :value="selectedVMData.ips?.join(', ') || 'None'" | ||||
|           /> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|  | ||||
|       <!-- Networks Section --> | ||||
|       <CollapsibleSection  | ||||
|         v-if="selectedVMData.networks?.length"  | ||||
|         title="Network Interfaces"  | ||||
|         :initially-expanded="sections.networks" | ||||
|       > | ||||
|         <div class="cards-stack"> | ||||
|           <div v-for="network in selectedVMData.networks"  | ||||
|                :key="network.vni"  | ||||
|                class="detail-card" | ||||
|           > | ||||
|             <ValueCard title="Interface" :value="network.vni" /> | ||||
|             <ValueCard title="Type" :value="network.type" /> | ||||
|             <ValueCard title="MAC" :value="network.mac" /> | ||||
|             <ValueCard title="Source" :value="network.source" /> | ||||
|           </div> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|  | ||||
|       <!-- Storage Section --> | ||||
|       <CollapsibleSection  | ||||
|         v-if="selectedVMData.disks?.length"  | ||||
|         title="Storage"  | ||||
|         :initially-expanded="sections.storage" | ||||
|       > | ||||
|         <div class="cards-stack"> | ||||
|           <div v-for="disk in selectedVMData.disks"  | ||||
|                :key="disk.dev"  | ||||
|                class="detail-card" | ||||
|           > | ||||
|             <ValueCard title="Device" :value="disk.dev" /> | ||||
|             <ValueCard title="Type" :value="disk.type" /> | ||||
|             <ValueCard title="Bus" :value="disk.bus" /> | ||||
|             <ValueCard title="Source" :value="disk.name" /> | ||||
|           </div> | ||||
|         </div> | ||||
|       </CollapsibleSection> | ||||
|     </div> | ||||
|  | ||||
|     <!-- Loading and no-selection states --> | ||||
|     <div v-if="!selectedVMData && !showVMList" class="content-container"> | ||||
|       <div v-if="isLoading" class="loading-container"> | ||||
|         <div class="spinner-border text-primary" role="status"> | ||||
|           <span class="visually-hidden">Loading...</span> | ||||
|         </div> | ||||
|         <p class="mt-2 text-muted">Loading VM details...</p> | ||||
|   <!-- VM Details --> | ||||
|   <div v-if="selectedVMData && !showVMList" class="content-container"> | ||||
|     <CollapsibleSection title="VM Information" :initially-expanded="sections.info"> | ||||
|       <div class="info-grid-general"> | ||||
|         <ValueCard  | ||||
|           title="State"  | ||||
|           :value="selectedVMData.state || 'Unknown'" | ||||
|           :status="getStateColor(selectedVMData.state)" | ||||
|         /> | ||||
|         <ValueCard  | ||||
|           title="Node"  | ||||
|           :value="selectedVMData.node || 'N/A'" | ||||
|         /> | ||||
|         <ValueCard  | ||||
|           title="CPUs"  | ||||
|           :value="selectedVMData.vcpus || 0" | ||||
|         /> | ||||
|         <ValueCard  | ||||
|           title="Memory"  | ||||
|           :value="formatMemory(selectedVMData.memory)" | ||||
|         /> | ||||
|       </div> | ||||
|       <div v-else class="no-content-message"> | ||||
|         <div class="alert alert-info"> | ||||
|           <i class="fas fa-info-circle me-2"></i> | ||||
|           <span v-if="invalidVMSelected"> | ||||
|             Selected VM does not exist | ||||
|           </span> | ||||
|           <span v-else> | ||||
|             Please select a VM from the list to view its details | ||||
|           </span> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|     <!-- Resources Section --> | ||||
|     <CollapsibleSection title="Resources" :initially-expanded="sections.resources"> | ||||
|       <div class="info-grid-resources"> | ||||
|         <ValueCard  | ||||
|           title="Disk Size"  | ||||
|           :value="formatStorage(selectedVMData.disk_size)" | ||||
|         /> | ||||
|         <ValueCard  | ||||
|           title="Network IPs"  | ||||
|           :value="selectedVMData.ips?.join(', ') || 'None'" | ||||
|         /> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|     <!-- Networks Section --> | ||||
|     <CollapsibleSection  | ||||
|       v-if="selectedVMData.networks?.length"  | ||||
|       title="Network Interfaces"  | ||||
|       :initially-expanded="sections.networks" | ||||
|     > | ||||
|       <div class="cards-stack"> | ||||
|         <div v-for="network in selectedVMData.networks"  | ||||
|               :key="network.vni"  | ||||
|               class="detail-card" | ||||
|         > | ||||
|           <ValueCard title="Interface" :value="network.vni" /> | ||||
|           <ValueCard title="Type" :value="network.type" /> | ||||
|           <ValueCard title="MAC" :value="network.mac" /> | ||||
|           <ValueCard title="Source" :value="network.source" /> | ||||
|         </div> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|  | ||||
|     <!-- Storage Section --> | ||||
|     <CollapsibleSection  | ||||
|       v-if="selectedVMData.disks?.length"  | ||||
|       title="Storage"  | ||||
|       :initially-expanded="sections.storage" | ||||
|     > | ||||
|       <div class="cards-stack"> | ||||
|         <div v-for="disk in selectedVMData.disks"  | ||||
|               :key="disk.dev"  | ||||
|               class="detail-card" | ||||
|         > | ||||
|           <ValueCard title="Device" :value="disk.dev" /> | ||||
|           <ValueCard title="Type" :value="disk.type" /> | ||||
|           <ValueCard title="Bus" :value="disk.bus" /> | ||||
|           <ValueCard title="Source" :value="disk.name" /> | ||||
|         </div> | ||||
|       </div> | ||||
|     </CollapsibleSection> | ||||
|   </div> | ||||
|  | ||||
|   <!-- Loading and no-selection states --> | ||||
|   <div v-if="!selectedVMData && !showVMList" class="content-container"> | ||||
|     <div v-if="isLoading" class="loading-container"> | ||||
|       <div class="spinner-border text-primary" role="status"> | ||||
|         <span class="visually-hidden">Loading...</span> | ||||
|       </div> | ||||
|       <p class="mt-2 text-muted">Loading VM details...</p> | ||||
|     </div> | ||||
|     <div v-else class="no-content-message"> | ||||
|       <div class="alert alert-info"> | ||||
|         <i class="fas fa-info-circle me-2"></i> | ||||
|         <span v-if="invalidVMSelected"> | ||||
|           Selected VM does not exist | ||||
|         </span> | ||||
|         <span v-else> | ||||
|           Please select a VM from the list to view its details | ||||
|         </span> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| @@ -318,17 +316,12 @@ const formatStorage = (sizeGB) => { | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .overview-container { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 0.5rem; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .content-container { | ||||
|   background-color: white; | ||||
|   border-radius: 0.25rem; | ||||
|   padding: 1rem; | ||||
|   width: 100%; | ||||
|   padding-top: 0.25rem; | ||||
| } | ||||
|  | ||||
| .loading-container { | ||||
|   | ||||
| @@ -39,9 +39,4 @@ const props = defineProps({ | ||||
|   gap: 0.5rem; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| /* Remove top margin from first child (usually PageTitle) */ | ||||
| .content-grid > :first-child { | ||||
|   margin-top: 0 !important; | ||||
| } | ||||
| </style> | ||||
| @@ -44,9 +44,4 @@ const props = defineProps({ | ||||
|   gap: 0.5rem; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| /* Remove top margin from first child (usually PageTitle) */ | ||||
| .content-grid > :first-child { | ||||
|   margin-top: 0 !important; | ||||
| } | ||||
| </style>  | ||||
		Reference in New Issue
	
	Block a user