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