BreweryControlSystem/code/src/material_tab.rs

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,
}
}
}