601 lines
27 KiB
Rust
601 lines
27 KiB
Rust
use std::{collections::HashMap, default::Default, sync::Arc};
|
|
|
|
use egui::mutex::RwLock;
|
|
use egui_extras::{Column, TableBuilder};
|
|
|
|
use crate::{
|
|
database::DBOperator,
|
|
misc::ELEMENTS_PER_PAGE,
|
|
models::{Material, MaterialCategory, MaterialRow, ModalStatus, ModalWinState},
|
|
tab::{TABS_CAN_BE_WINDOWS, Tab, TabTypes},
|
|
};
|
|
|
|
pub struct MaterialTabViewer {
|
|
db_oper: DBOperator,
|
|
rt: tokio::runtime::Runtime,
|
|
process_mcat_state: ModalWinState,
|
|
|
|
process_material_state: ModalWinState,
|
|
|
|
mat_cats: Arc<RwLock<Vec<MaterialCategory>>>,
|
|
mats: Arc<RwLock<Vec<Material>>>,
|
|
is_admin: bool,
|
|
mat_page: i32,
|
|
mcat_page: i32,
|
|
}
|
|
impl MaterialTabViewer {
|
|
pub fn new(is_admin: bool) -> Self {
|
|
Self {
|
|
is_admin,
|
|
..Default::default()
|
|
}
|
|
}
|
|
fn update_material_category(&mut self) {
|
|
self.mat_cats = Arc::new(RwLock::new(
|
|
self.rt
|
|
.block_on(async { self.db_oper.get_mcat().await.unwrap() }),
|
|
));
|
|
}
|
|
fn update_materials(&mut self) {
|
|
self.mats = Arc::new(RwLock::new(self.rt.block_on(async {
|
|
self.db_oper
|
|
.get_materials(self.mat_page * ELEMENTS_PER_PAGE, ELEMENTS_PER_PAGE)
|
|
.await
|
|
.unwrap()
|
|
})));
|
|
}
|
|
fn show_material(&mut self, ui: &mut egui::Ui) {
|
|
ui.horizontal(|ui| {
|
|
if self.is_admin {
|
|
if ui.button("Добавить").clicked() {
|
|
self.process_material_state.is_open = true;
|
|
self.process_material_state.status = ModalStatus::Add;
|
|
}
|
|
// if ui.button("Удалить").clicked() {
|
|
// self.process_material_state.is_open = true;
|
|
// self.process_material_state.status = ModalStatus::Remove;
|
|
// }
|
|
}
|
|
if ui.button("Обновить").clicked() {
|
|
self.update_materials();
|
|
}
|
|
});
|
|
|
|
TableBuilder::new(ui)
|
|
.striped(true)
|
|
.cell_layout(egui::Layout::centered_and_justified(
|
|
egui::Direction::LeftToRight,
|
|
))
|
|
.vscroll(true)
|
|
.column(Column::auto())
|
|
.column(Column::auto())
|
|
.column(Column::auto())
|
|
.sense(egui::Sense::click())
|
|
.header(20.0, |mut header| {
|
|
header.col(|ui| {
|
|
ui.heading("Название");
|
|
});
|
|
header.col(|ui| {
|
|
ui.heading("Тип");
|
|
});
|
|
header.col(|ui| {
|
|
ui.heading("Количество");
|
|
});
|
|
})
|
|
.body(|mut body| {
|
|
body.ui_mut().style_mut().interaction.selectable_labels = false;
|
|
self.rt.block_on(async {
|
|
for mat in self.mats.read().clone().iter() {
|
|
body.row(30.0, |mut row| {
|
|
row.col(|ui| {
|
|
ui.label(&mat.name);
|
|
});
|
|
row.col(|ui| {
|
|
ui.label(&mat.category.name);
|
|
});
|
|
row.col(|ui| {
|
|
ui.label(mat.quantity.to_string());
|
|
});
|
|
if row.response().double_clicked() {
|
|
self.process_material_state.is_open = true;
|
|
self.process_material_state.status = ModalStatus::Edit;
|
|
self.process_material_state
|
|
.data
|
|
.insert("id".into(), mat.id.to_string());
|
|
self.process_material_state
|
|
.data
|
|
.insert("name".into(), mat.name.to_string());
|
|
self.process_material_state
|
|
.data
|
|
.insert("category_id".into(), mat.category.id.to_string());
|
|
self.process_material_state
|
|
.data
|
|
.insert("quantity".into(), mat.quantity.to_string());
|
|
}
|
|
});
|
|
}
|
|
})
|
|
});
|
|
if self.process_material_state.is_open {
|
|
egui::Modal::new("process_material".into()).show(ui.ctx(), |ui| {
|
|
if ui.button("Закрыть").clicked() {
|
|
self.process_material_state.is_open = false;
|
|
}
|
|
egui::Grid::new("process_material_grid").show(ui, |ui| {
|
|
let old = self.process_material_state.data.get("id").unwrap().clone();
|
|
if self.process_material_state.status != ModalStatus::Add {
|
|
ui.label("Материал");
|
|
|
|
let mats = self.mats.read().clone();
|
|
|
|
let sel_id = self
|
|
.process_material_state
|
|
.data
|
|
.get("id")
|
|
.map(|d| d.as_str())
|
|
.unwrap_or("");
|
|
let cur_name = mats
|
|
.iter()
|
|
.find(|m| m.id.to_string() == sel_id)
|
|
.map(|m| m.name.clone())
|
|
.unwrap_or_default();
|
|
egui::ComboBox::from_id_salt("process_material_combobox_mat")
|
|
.selected_text(cur_name)
|
|
.show_ui(ui, |ui| {
|
|
for mat in self.mats.read().iter().clone() {
|
|
ui.selectable_value(
|
|
self.process_material_state.data.get_mut("id").unwrap(),
|
|
mat.id.to_string(),
|
|
&mat.name,
|
|
);
|
|
}
|
|
let id = self
|
|
.process_material_state
|
|
.data
|
|
.get_mut("id")
|
|
.unwrap()
|
|
.clone();
|
|
if id != old {
|
|
self.process_material_state.data.insert(
|
|
"name".to_owned(),
|
|
mats.iter()
|
|
.find(|m| m.id.to_string() == id)
|
|
.unwrap()
|
|
.name
|
|
.clone(),
|
|
);
|
|
self.process_material_state.data.insert(
|
|
"quantity".to_owned(),
|
|
mats.iter()
|
|
.find(|m| m.id.to_string() == id)
|
|
.unwrap()
|
|
.quantity
|
|
.to_string(),
|
|
);
|
|
self.process_material_state.data.insert(
|
|
"category_id".to_owned(),
|
|
mats.iter()
|
|
.find(|m| m.id.to_string() == id)
|
|
.unwrap()
|
|
.category
|
|
.id
|
|
.to_string(),
|
|
);
|
|
}
|
|
});
|
|
ui.end_row();
|
|
}
|
|
let old = self
|
|
.process_material_state
|
|
.data
|
|
.get("category_id")
|
|
.unwrap()
|
|
.clone();
|
|
if self.process_material_state.status != ModalStatus::Remove {
|
|
ui.label("Название");
|
|
ui.text_edit_singleline(
|
|
self.process_material_state.data.get_mut("name").unwrap(),
|
|
);
|
|
|
|
ui.end_row();
|
|
ui.label("Количество");
|
|
ui.text_edit_singleline(
|
|
self.process_material_state
|
|
.data
|
|
.get_mut("quantity")
|
|
.unwrap(),
|
|
);
|
|
|
|
ui.end_row();
|
|
ui.label("Тип");
|
|
|
|
let mats = self.mat_cats.read().clone();
|
|
|
|
let sel_id = self
|
|
.process_material_state
|
|
.data
|
|
.get("category_id")
|
|
.map(|d| d.as_str())
|
|
.unwrap_or_default();
|
|
let cur_name = mats
|
|
.iter()
|
|
.find(|m| m.id.to_string() == sel_id)
|
|
.map(|m| m.name.clone())
|
|
.unwrap_or_default();
|
|
egui::ComboBox::from_id_salt("process_material_combobox_cat")
|
|
.selected_text(cur_name)
|
|
.show_ui(ui, |ui| {
|
|
for mat in self.mat_cats.read().iter() {
|
|
ui.selectable_value(
|
|
self.process_material_state
|
|
.data
|
|
.get_mut("category_id")
|
|
.unwrap(),
|
|
mat.id.to_string(),
|
|
&mat.name.clone(),
|
|
);
|
|
}
|
|
});
|
|
ui.end_row();
|
|
}
|
|
});
|
|
match self.process_material_state.status {
|
|
ModalStatus::Add => {
|
|
let resp = ui.add_enabled(
|
|
self.process_material_state.data.get("name").unwrap().len() > 0
|
|
&& self
|
|
.process_material_state
|
|
.data
|
|
.get("quantity")
|
|
.unwrap()
|
|
.len()
|
|
> 0,
|
|
egui::Button::new("Добавить"),
|
|
);
|
|
if resp.clicked() {
|
|
self.rt.block_on(async {
|
|
self.db_oper
|
|
.add_material(MaterialRow {
|
|
id: self
|
|
.process_material_state
|
|
.data
|
|
.get("id")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
name: self
|
|
.process_material_state
|
|
.data
|
|
.get("name")
|
|
.unwrap()
|
|
.to_string(),
|
|
quantity: self
|
|
.process_material_state
|
|
.data
|
|
.get("quantity")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
category_id: self
|
|
.process_material_state
|
|
.data
|
|
.get("category_id")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
});
|
|
self.update_materials();
|
|
self.process_material_state.is_open = false;
|
|
}
|
|
}
|
|
ModalStatus::Edit => {
|
|
if ui.button("Сохранить").clicked() {
|
|
self.rt.block_on(async {
|
|
self.db_oper
|
|
.update_material(MaterialRow {
|
|
id: self
|
|
.process_material_state
|
|
.data
|
|
.get("id")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
name: self
|
|
.process_material_state
|
|
.data
|
|
.get("name")
|
|
.unwrap()
|
|
.to_string(),
|
|
quantity: self
|
|
.process_material_state
|
|
.data
|
|
.get("quantity")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
category_id: self
|
|
.process_material_state
|
|
.data
|
|
.get("category_id")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
});
|
|
self.update_materials();
|
|
self.process_material_state.is_open = false;
|
|
}
|
|
}
|
|
ModalStatus::Remove => {
|
|
if ui.button("Удалить").clicked() {
|
|
self.rt.block_on(async {
|
|
self.db_oper
|
|
.delete_material(MaterialRow {
|
|
id: self
|
|
.process_material_state
|
|
.data
|
|
.get("id")
|
|
.unwrap()
|
|
.parse::<i32>()
|
|
.unwrap(),
|
|
name: "".to_owned(),
|
|
quantity: 0,
|
|
category_id: 0,
|
|
})
|
|
.await
|
|
.unwrap();
|
|
});
|
|
self.update_materials();
|
|
self.process_material_state.is_open = false;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
fn show_material_category(&mut self, ui: &mut egui::Ui) {
|
|
ui.horizontal(|ui| {
|
|
if self.is_admin {
|
|
if ui.button("Добавить").clicked() {
|
|
self.process_mcat_state.is_open = true;
|
|
self.process_mcat_state.status = ModalStatus::Add;
|
|
}
|
|
}
|
|
if ui.button("Обновить").clicked() {
|
|
self.update_material_category();
|
|
}
|
|
});
|
|
if self.process_mcat_state.is_open {
|
|
egui::Modal::new("process_mcat".into()).show(ui.ctx(), |ui| {
|
|
if ui.button("Закрыть").clicked() {
|
|
self.process_mcat_state.is_open = false;
|
|
}
|
|
egui::Grid::new("process_mcat_grid").show(ui, |ui| {
|
|
let old = self.process_mcat_state.data.get("id").unwrap().clone();
|
|
let iterr = self.mat_cats.read().clone();
|
|
|
|
let selected_id = self
|
|
.process_mcat_state
|
|
.data
|
|
.get("id")
|
|
.map(|s| s.as_str())
|
|
.unwrap_or("");
|
|
|
|
let current_name = iterr
|
|
.iter()
|
|
.find(|mc| mc.id.to_string() == *selected_id)
|
|
.map(|mc| mc.name.as_str())
|
|
.unwrap_or("Выбрать");
|
|
if self.process_mcat_state.status != ModalStatus::Add {
|
|
ui.label("Тип");
|
|
egui::ComboBox::new("process_mcat_grid_selector", "Выбрать")
|
|
.selected_text(current_name)
|
|
.show_ui(ui, |ui| {
|
|
self.rt.block_on(async {
|
|
for mcat in iterr {
|
|
ui.selectable_value(
|
|
self.process_mcat_state.data.get_mut("id").unwrap(),
|
|
mcat.id.to_string(),
|
|
format!("{}|{}", mcat.id, &mcat.name),
|
|
);
|
|
}
|
|
});
|
|
});
|
|
ui.end_row();
|
|
}
|
|
let current_id = self.process_mcat_state.data.get("id").unwrap().clone();
|
|
if self.process_mcat_state.data.get("id").unwrap() != &old {
|
|
self.process_mcat_state.data.insert(
|
|
"name".to_owned(),
|
|
self.mat_cats
|
|
.read()
|
|
.iter()
|
|
.find(|mc| mc.id.to_string() == current_id)
|
|
.unwrap()
|
|
.name
|
|
.clone(),
|
|
);
|
|
}
|
|
|
|
if self.process_mcat_state.status != ModalStatus::Remove {
|
|
ui.label("Название");
|
|
let mut name = self.process_mcat_state.data.get_mut("name").unwrap();
|
|
ui.text_edit_singleline(name);
|
|
ui.end_row();
|
|
}
|
|
|
|
match self.process_mcat_state.status {
|
|
ModalStatus::Add => {
|
|
if ui.button("Добавить").clicked() {
|
|
let name =
|
|
self.process_mcat_state.data.get("name").unwrap().clone();
|
|
self.rt.block_on(async {
|
|
self.db_oper
|
|
.add_material_category(MaterialCategory { id: 0, name })
|
|
.await
|
|
.unwrap();
|
|
});
|
|
self.update_material_category();
|
|
self.process_mcat_state.is_open = false;
|
|
}
|
|
}
|
|
ModalStatus::Edit => {
|
|
if ui.button("Сохранить").clicked() {
|
|
let id = self.process_mcat_state.data.get("id").unwrap().clone();
|
|
let name =
|
|
self.process_mcat_state.data.get("name").unwrap().clone();
|
|
self.rt.block_on(async {
|
|
self.db_oper
|
|
.update_material_category(MaterialCategory {
|
|
id: id.parse::<i32>().unwrap(),
|
|
name: name.clone(),
|
|
})
|
|
.await
|
|
.unwrap()
|
|
});
|
|
println!("{}", &name);
|
|
self.update_material_category();
|
|
self.process_mcat_state.is_open = false;
|
|
}
|
|
}
|
|
ModalStatus::Remove => {
|
|
if ui.button("Удалить").clicked() {
|
|
let idd = self.process_mcat_state.data.get("id").unwrap().clone();
|
|
self.rt.block_on(async {
|
|
self.db_oper
|
|
.delete_material_category(MaterialCategory {
|
|
id: idd.parse::<i32>().unwrap(),
|
|
name: "".to_owned(),
|
|
})
|
|
.await
|
|
.unwrap()
|
|
});
|
|
self.update_material_category();
|
|
self.process_mcat_state.is_open = false;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
TableBuilder::new(ui)
|
|
.striped(true)
|
|
.column(Column::auto())
|
|
.column(Column::auto())
|
|
.sense(egui::Sense::click())
|
|
.header(20.0, |mut header| {
|
|
header.col(|ui| {
|
|
ui.heading("ID");
|
|
});
|
|
header.col(|ui| {
|
|
ui.heading("Название");
|
|
});
|
|
})
|
|
.body(|mut body| {
|
|
self.rt.block_on(async {
|
|
for mcat in self.mat_cats.read().clone().iter() {
|
|
body.row(20.0, |mut row| {
|
|
row.col(|ui| {
|
|
ui.label(mcat.id.to_string());
|
|
});
|
|
row.col(|ui| {
|
|
ui.label(&mcat.name);
|
|
});
|
|
if row.response().double_clicked() {
|
|
self.process_mcat_state.is_open = true;
|
|
self.process_mcat_state.status = ModalStatus::Edit;
|
|
self.process_mcat_state
|
|
.data
|
|
.insert("id".into(), mcat.id.to_string());
|
|
self.process_mcat_state
|
|
.data
|
|
.insert("name".into(), mcat.name.clone());
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
impl egui_dock::TabViewer for MaterialTabViewer {
|
|
type Tab = Tab;
|
|
fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
|
|
(&*tab.title).into()
|
|
}
|
|
fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
|
|
match &tab.tab_type {
|
|
TabTypes::MaterialList => self.show_material(ui),
|
|
TabTypes::MaterialTypeList => self.show_material_category(ui),
|
|
_ => {
|
|
ui.label("Каким образом?");
|
|
}
|
|
}
|
|
}
|
|
fn allowed_in_windows(&self, _tab: &mut Self::Tab) -> bool {
|
|
TABS_CAN_BE_WINDOWS
|
|
}
|
|
fn is_closeable(&self, _tab: &Self::Tab) -> bool {
|
|
false
|
|
}
|
|
}
|
|
impl Default for MaterialTabViewer {
|
|
fn default() -> Self {
|
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
let db_oper = rt.block_on(async { DBOperator::new().await });
|
|
let mat_cats = Arc::new(RwLock::new(
|
|
rt.block_on(async { db_oper.get_mcat().await.unwrap() }),
|
|
));
|
|
let mats = Arc::new(RwLock::new(rt.block_on(async {
|
|
db_oper.get_materials(0, ELEMENTS_PER_PAGE).await.unwrap()
|
|
})));
|
|
Self {
|
|
db_oper,
|
|
rt,
|
|
process_mcat_state: ModalWinState {
|
|
data: HashMap::from([
|
|
(
|
|
String::from("id"),
|
|
mat_cats.clone().read().clone()[0].id.to_string(),
|
|
),
|
|
(
|
|
String::from("name"),
|
|
mat_cats.clone().read().clone()[0].name.clone(),
|
|
),
|
|
]),
|
|
status: ModalStatus::Add,
|
|
..Default::default()
|
|
},
|
|
|
|
process_material_state: ModalWinState {
|
|
data: HashMap::from([
|
|
(
|
|
"id".to_owned(),
|
|
mats.clone().read().clone()[0].id.to_string(),
|
|
),
|
|
(
|
|
"name".to_owned(),
|
|
mats.clone().read().clone()[0].name.clone(),
|
|
),
|
|
(
|
|
"quantity".to_owned(),
|
|
mats.clone().read().clone()[0].quantity.to_string(),
|
|
),
|
|
("category_id".to_owned(), "1".to_owned()),
|
|
]),
|
|
..Default::default()
|
|
},
|
|
mat_cats,
|
|
mats,
|
|
is_admin: false,
|
|
mat_page: 0,
|
|
mcat_page: 0,
|
|
}
|
|
}
|
|
}
|