Add more search bar features

This commit is contained in:
Joshua Boniface 2025-03-02 15:05:41 -05:00
parent 745d554768
commit 5b691d0e5b

View File

@ -46,7 +46,7 @@
</button> </button>
<div class="filter-menu" v-show="showFilterMenu" ref="filterMenu"> <div class="filter-menu" v-show="showFilterMenu" ref="filterMenu">
<div class="filter-section"> <div class="filter-section">
<h6>Status</h6> <h6>State</h6>
<div class="filter-options-dropdown"> <div class="filter-options-dropdown">
<div class="filter-pills"> <div class="filter-pills">
<button <button
@ -104,10 +104,14 @@
<div v-if="selectedVM === vm.name || vmFromUrl === vm.name" class="active-indicator"></div> <div v-if="selectedVM === vm.name || vmFromUrl === vm.name" class="active-indicator"></div>
<div class="vm-item-content"> <div class="vm-item-content">
<div class="vm-name">{{ vm.name }}</div> <div class="vm-name">{{ vm.name }}</div>
<div class="vm-status" :class="getStatusClass(vm.state)"> <div class="vm-state" :class="getStateClass(vm.state)">
<i class="fas fa-circle status-indicator"></i> <i class="fas fa-circle state-indicator"></i>
<span>{{ vm.state }}</span> <span>{{ vm.state }}</span>
</div> </div>
<div v-if="vm.node" class="vm-node">
<i class="fas fa-server node-icon"></i>
<span>{{ vm.node }}</span>
</div>
</div> </div>
</button> </button>
</div> </div>
@ -435,7 +439,24 @@ const availableStates = computed(() => {
props.vmList.forEach(vm => { props.vmList.forEach(vm => {
if (vm.state) states.add(vm.state); if (vm.state) states.add(vm.state);
}); });
return Array.from(states).sort();
// Convert to array and ensure all important states are included
const statesArray = Array.from(states);
const importantStates = ['start', 'disable', 'migrate', 'unmigrate', 'provision', 'mirror', 'stop', 'fail', 'shutdown', 'restart'];
// Add any missing important states
importantStates.forEach(state => {
if (!statesArray.includes(state)) {
statesArray.push(state);
}
});
// Sort with 'start' first, then alphabetically
return statesArray.sort((a, b) => {
if (a.toLowerCase() === 'start') return -1;
if (b.toLowerCase() === 'start') return 1;
return a.localeCompare(b);
});
}); });
// Calculate available nodes from vmList // Calculate available nodes from vmList
@ -479,15 +500,39 @@ const activeFiltersCount = computed(() => {
return count; return count;
}); });
// Status class helper // Update function name from getStatusClass to getStateClass
const getStatusClass = (state) => { const getStateClass = (state) => {
if (!state) return 'status-unknown'; if (!state) return 'status-unknown';
switch(state.toLowerCase()) {
case 'start': return 'status-running'; const lowerState = state.toLowerCase();
case 'stop': return 'status-stopped';
case 'disable': return 'status-paused'; // Green for running VMs
default: return 'status-unknown'; if (lowerState === 'start') {
return 'status-running';
} }
// Blue for provisioning, migration, etc.
if (['disable', 'migrate', 'unmigrate', 'provision'].includes(lowerState)) {
return 'status-provisioning';
}
// Purple for mirror
if (lowerState === 'mirror') {
return 'status-mirror';
}
// Red for stopped or failed VMs
if (['stop', 'fail'].includes(lowerState)) {
return 'status-stopped';
}
// Yellow for shutdown or restart
if (['shutdown', 'restart'].includes(lowerState)) {
return 'status-restarting';
}
// Default to unknown (black) for any other states
return 'status-unknown';
}; };
// Watch for changes in showList // Watch for changes in showList
@ -720,45 +765,60 @@ const loadFiltersFromLocalStorage = () => {
.vm-item-content { .vm-item-content {
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
width: 100%; width: 100%;
gap: 1rem;
} }
.vm-name { .vm-name {
font-weight: 500; font-weight: 500;
flex: 1;
} }
.vm-status { .vm-state {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
font-size: 0.875rem; font-size: 0.875rem;
width: 100px;
} }
.status-indicator { .vm-node {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
color: #6c757d;
width: 100px;
}
.node-icon {
font-size: 0.75rem;
}
.state-indicator {
font-size: 0.625rem; font-size: 0.625rem;
} }
/* Status colors */ /* Status colors - updated */
.status-running { .status-running {
color: #28a745; color: #28a745; /* Green */
} }
.status-stopped { .status-stopped {
color: #6c757d; color: #dc3545; /* Red */
} }
.status-paused { .status-provisioning {
color: #ffc107; color: #0d6efd; /* Blue */
} }
.status-error { .status-mirror {
color: #dc3545; color: #6f42c1; /* Purple */
} }
.status-unknown { .status-restarting {
color: #6c757d; color: #ffc107; /* Yellow */
} }
.no-vms-message { .no-vms-message {
@ -773,7 +833,7 @@ const loadFiltersFromLocalStorage = () => {
top: 100%; top: 100%;
right: 0; right: 0;
z-index: 1000; z-index: 1000;
min-width: 250px; min-width: 350px;
padding: 1rem; padding: 1rem;
margin-top: 0.5rem; margin-top: 0.5rem;
background-color: white; background-color: white;
@ -794,7 +854,7 @@ const loadFiltersFromLocalStorage = () => {
} }
.filter-options-dropdown { .filter-options-dropdown {
max-height: 150px; max-height: 200px;
overflow-y: auto; overflow-y: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;