Unify and clean up position styling

This commit is contained in:
Joshua Boniface 2025-03-02 17:06:47 -05:00
parent 4ca93fcc9a
commit e11217e28a
8 changed files with 257 additions and 282 deletions

View File

@ -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>

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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>

View File

@ -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>