fix: 节点和虚拟机列表存储到AppState,自动更新选中的节点
This commit is contained in:
66
src/gui.rs
66
src/gui.rs
@@ -87,6 +87,8 @@ pub struct AppState {
|
||||
pub client: Arc<Mutex<Option<ProxmoxClient>>>,
|
||||
pub vm_id: u32,
|
||||
pub node: String,
|
||||
pub nodes: Vec<String>,
|
||||
pub vms: Vec<(u32, String)>,
|
||||
pub vm_status: String,
|
||||
pub log_buffer: Vec<String>,
|
||||
pub is_connected: bool,
|
||||
@@ -114,6 +116,8 @@ impl AppState {
|
||||
client,
|
||||
vm_id: config.vm_id,
|
||||
node: config.node.clone(),
|
||||
nodes: Vec::new(),
|
||||
vms: Vec::new(),
|
||||
vm_status: "未知".to_string(),
|
||||
log_buffer: log,
|
||||
is_connected: false,
|
||||
@@ -136,18 +140,6 @@ pub struct SettingsData {
|
||||
pub token_secret: String,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NodesData {
|
||||
pub nodes: Vec<String>,
|
||||
pub selected_index: usize,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct VmListData {
|
||||
pub vms: Vec<(u32, String)>,
|
||||
pub selected_index: usize,
|
||||
}
|
||||
|
||||
pub fn gui_run() {
|
||||
let options = NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default()
|
||||
@@ -181,8 +173,6 @@ struct App {
|
||||
state: SharedState,
|
||||
show_settings: bool,
|
||||
settings: SettingsData,
|
||||
nodes: NodesData,
|
||||
vms: VmListData,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@@ -199,8 +189,6 @@ impl App {
|
||||
state: Arc::new(RwLock::new(AppState::new(&config))),
|
||||
show_settings: false,
|
||||
settings,
|
||||
nodes: NodesData::default(),
|
||||
vms: VmListData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,21 +225,22 @@ impl eframe::App for App {
|
||||
ui.add_space(4.0);
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("节点:");
|
||||
if self.nodes.nodes.is_empty() {
|
||||
if st.nodes.is_empty() {
|
||||
ui.label("无节点");
|
||||
} else {
|
||||
let selected = st.nodes[st.nodes.len().saturating_sub(1)].clone();
|
||||
egui::ComboBox::from_id_salt("node_combo")
|
||||
.selected_text(&self.nodes.nodes[self.nodes.selected_index.min(self.nodes.nodes.len().saturating_sub(1))])
|
||||
.selected_text(&selected)
|
||||
.show_ui(ui, |ui| {
|
||||
for (i, node) in self.nodes.nodes.iter().enumerate() {
|
||||
ui.selectable_value(&mut self.nodes.selected_index, i, node);
|
||||
for node in st.nodes.iter() {
|
||||
if ui.selectable_value(&mut st.node.clone(), node.clone(), node).clicked() {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if ui.button("🔄节点").clicked() {
|
||||
let client = st.client.clone();
|
||||
let state_clone = state.clone();
|
||||
let nodes_clone = Arc::new(RwLock::new(Vec::<String>::new()));
|
||||
st.add_log("正在获取节点列表...");
|
||||
ctx.request_repaint();
|
||||
thread::spawn(move || {
|
||||
@@ -263,8 +252,11 @@ impl eframe::App for App {
|
||||
Ok(nodes) => {
|
||||
let mut state = state_clone.write().unwrap();
|
||||
state.is_connected = true;
|
||||
state.nodes = nodes.clone();
|
||||
if !nodes.is_empty() {
|
||||
state.add_log(&format!("✓ 连接成功,找到节点: {:?}", nodes));
|
||||
state.node = nodes[0].clone();
|
||||
state.add_log(&format!("✓ 连接成功,节点: {}", nodes[0]));
|
||||
state.add_log(&format!(" 全部节点: {:?}", nodes));
|
||||
} else {
|
||||
state.add_log("未找到节点");
|
||||
}
|
||||
@@ -283,25 +275,18 @@ impl eframe::App for App {
|
||||
ui.add_space(4.0);
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("虚拟机:");
|
||||
if self.vms.vms.is_empty() {
|
||||
if st.vms.is_empty() {
|
||||
ui.label("无虚拟机");
|
||||
} else {
|
||||
let vm_names: Vec<String> = self.vms.vms.iter().map(|(id, name)| format!("{} ({})", name, id)).collect();
|
||||
egui::ComboBox::from_id_salt("vm_combo")
|
||||
.selected_text(&vm_names[self.vms.selected_index.min(vm_names.len().saturating_sub(1))])
|
||||
.show_ui(ui, |ui| {
|
||||
for (i, (_, name)) in self.vms.vms.iter().enumerate() {
|
||||
if ui.selectable_value(&mut self.vms.selected_index, i, format!("{} ({})", name, self.vms.vms[i].0)).clicked() {
|
||||
st.vm_id = self.vms.vms[i].0;
|
||||
}
|
||||
}
|
||||
});
|
||||
let vm_count = st.vms.len();
|
||||
let first_vm = st.vms.first().map(|(id, name)| format!("{} ({})", name, id)).unwrap_or_default();
|
||||
ui.label(format!("{} 共{}台", first_vm, vm_count));
|
||||
}
|
||||
if ui.button("🔄VM").clicked() {
|
||||
if self.nodes.nodes.is_empty() {
|
||||
if st.nodes.is_empty() {
|
||||
st.add_log("请先获取节点列表");
|
||||
} else {
|
||||
let node = self.nodes.nodes[self.nodes.selected_index.min(self.nodes.nodes.len().saturating_sub(1))].clone();
|
||||
let node = st.node.clone();
|
||||
let client = st.client.clone();
|
||||
let state_clone = state.clone();
|
||||
st.add_log(&format!("正在获取 {} 的虚拟机列表...", node));
|
||||
@@ -313,17 +298,20 @@ impl eframe::App for App {
|
||||
if let Some(c) = client.as_ref() {
|
||||
match c.get_vms(&node).await {
|
||||
Ok(vms) => {
|
||||
let mut state = state_clone.write().unwrap();
|
||||
if !vms.is_empty() {
|
||||
state_clone.write().unwrap().add_log(&format!("找到 {} 台虚拟机", vms.len()));
|
||||
state.vms = vms.clone();
|
||||
state.vm_id = vms[0].0;
|
||||
state.add_log(&format!("✓ 找到 {} 台虚拟机", vms.len()));
|
||||
for (id, name) in &vms {
|
||||
state_clone.write().unwrap().add_log(&format!(" - {} ({})", name, id));
|
||||
state.add_log(&format!(" {} ({})", name, id));
|
||||
}
|
||||
} else {
|
||||
state_clone.write().unwrap().add_log("未找到虚拟机");
|
||||
state.add_log("未找到虚拟机");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
state_clone.write().unwrap().add_log(&format!("获取虚拟机失败: {}", e));
|
||||
state_clone.write().unwrap().add_log(&format!("✗ 获取虚拟机失败: {}", e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user