UI update - almost working
This commit is contained in:
parent
de2504cdb1
commit
f028064630
6 changed files with 225 additions and 177 deletions
|
@ -1,5 +1,5 @@
|
||||||
use super::csv_handler::{DataEntry, ImportedData};
|
use super::csv_handler::{DataEntry, ImportedData};
|
||||||
use super::database_handler::{DBLoginData, QueryResult, Table, TableField, Tables};
|
use super::database_handler::{DBLoginData, QueryResult, Table, Tables};
|
||||||
use super::parser::parse;
|
use super::parser::parse;
|
||||||
use sqlx::MySqlConnection;
|
use sqlx::MySqlConnection;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -55,6 +55,9 @@ impl BackendManger {
|
||||||
println!("{}", e);
|
println!("{}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut db_table_data = self.db_table_data.lock().await;
|
||||||
|
let mut csv_data = self.csv_data.lock().await;
|
||||||
|
try_match_headers_to_fields(&mut db_table_data, None, &mut csv_data)
|
||||||
}
|
}
|
||||||
Communication::ImportDBEntries(usize) => {
|
Communication::ImportDBEntries(usize) => {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -72,45 +75,11 @@ impl BackendManger {
|
||||||
.describe_table(&mut self.db_connection.as_mut().unwrap())
|
.describe_table(&mut self.db_connection.as_mut().unwrap())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match try_match_headers_to_fields(
|
try_match_headers_to_fields(
|
||||||
&mut db_table_data,
|
&mut db_table_data,
|
||||||
table_index,
|
Some(table_index),
|
||||||
&csv_data.data.iter_row(0),
|
&mut csv_data,
|
||||||
) {
|
);
|
||||||
Ok(_) => {
|
|
||||||
/* If some got automapped, try to parse them all */
|
|
||||||
for (col_index, field) in db_table_data
|
|
||||||
.tables
|
|
||||||
.get_mut(table_index)
|
|
||||||
.unwrap()
|
|
||||||
.fields
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.iter_mut()
|
|
||||||
.enumerate()
|
|
||||||
{
|
|
||||||
println!(
|
|
||||||
" > automapping field \"{}\" to col \"{:?}\"",
|
|
||||||
&field.description.field, field.mapped_to_col
|
|
||||||
);
|
|
||||||
if let Some(col_index) = field.mapped_to_col {
|
|
||||||
for cell in csv_data.data.iter_col_mut(col_index) {
|
|
||||||
cell.curr_field_description =
|
|
||||||
Some(field.description.clone());
|
|
||||||
parse(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_whole_col_parsed(&mut csv_data, col_index) {
|
|
||||||
println!("col \"{}\" is parsed whole!", &col_index);
|
|
||||||
csv_data.parsed_cols.push(col_index);
|
|
||||||
}
|
|
||||||
if is_whole_table_parsed(&csv_data) {
|
|
||||||
csv_data.is_parsed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Communication::RemoveRow(usize) => {
|
Communication::RemoveRow(usize) => {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -127,7 +96,7 @@ impl BackendManger {
|
||||||
}
|
}
|
||||||
if is_whole_col_parsed(&mut csv_data, col_index) {
|
if is_whole_col_parsed(&mut csv_data, col_index) {
|
||||||
println!("col \"{}\" is parsed whole!", &col_index);
|
println!("col \"{}\" is parsed whole!", &col_index);
|
||||||
csv_data.parsed_cols.push(col_index - 1);
|
csv_data.parsed_cols.push(col_index);
|
||||||
}
|
}
|
||||||
if is_whole_table_parsed(&csv_data) {
|
if is_whole_table_parsed(&csv_data) {
|
||||||
csv_data.is_parsed = true;
|
csv_data.is_parsed = true;
|
||||||
|
@ -198,27 +167,32 @@ pub fn is_whole_col_parsed(csv_data: &mut MutexGuard<ImportedData>, col_index: u
|
||||||
match parse {
|
match parse {
|
||||||
Ok(_) => return true,
|
Ok(_) => return true,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!(
|
|
||||||
"Cel \"{}\" in Col \"{}\" isnt parsed :(",
|
|
||||||
cel.data, col_index
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!(
|
|
||||||
"Cel \"{}\" in Col \"{}\" isnt parsed :(",
|
|
||||||
cel.data, col_index
|
|
||||||
);
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn try_match_headers_to_fields(
|
pub fn try_match_headers_to_fields(
|
||||||
tables: &mut MutexGuard<Tables>,
|
tables: &mut MutexGuard<Tables>,
|
||||||
table_index: usize,
|
table_index: Option<usize>,
|
||||||
csv_headers: &std::slice::Iter<'_, DataEntry>,
|
csv_data: &mut MutexGuard<ImportedData>,
|
||||||
) -> Result<(), ()> {
|
) {
|
||||||
|
if !csv_data.are_headers || csv_data.data.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let final_table_index: usize;
|
||||||
|
if let Some(i) = table_index {
|
||||||
|
final_table_index = i;
|
||||||
|
} else if let Some(cw_table_i) = tables.current_working_table {
|
||||||
|
final_table_index = cw_table_i;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let table_index = final_table_index;
|
||||||
|
|
||||||
let db_fields = tables
|
let db_fields = tables
|
||||||
.tables
|
.tables
|
||||||
.get_mut(table_index)
|
.get_mut(table_index)
|
||||||
|
@ -228,19 +202,49 @@ pub fn try_match_headers_to_fields(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut has_matched_some = false;
|
let mut has_matched_some = false;
|
||||||
for field in db_fields {
|
for field in db_fields {
|
||||||
for (i, header) in csv_headers.clone().enumerate() {
|
for (i, header) in csv_data.data.iter_row(0).into_iter().enumerate() {
|
||||||
if &field.description.field == &header.data {
|
if &field.description.field == &header.data {
|
||||||
field.mapped_to_col = Some(i);
|
field.mapped_to_col = Some(i);
|
||||||
has_matched_some = true;
|
has_matched_some = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match has_matched_some {
|
|
||||||
true => return Ok(()),
|
if has_matched_some == false
|
||||||
false => return Err(()),
|
|| tables.current_working_table.is_none()
|
||||||
|
|| tables.tables.is_empty()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* If some got automapped, try to parse them all */
|
||||||
|
if let Some(table_i) = tables.current_working_table {
|
||||||
|
if let Some(table) = tables.tables.get_mut(table_i) {
|
||||||
|
if let Some(fields) = table.fields.as_mut() {
|
||||||
|
for (col_index, field) in fields.iter().enumerate() {
|
||||||
|
println!(
|
||||||
|
" > automapping field \"{}\" to col \"{:?}\"",
|
||||||
|
&field.description.field, field.mapped_to_col
|
||||||
|
);
|
||||||
|
if let Some(col_index) = field.mapped_to_col {
|
||||||
|
for cell in csv_data.data.iter_mut() {
|
||||||
|
cell.curr_field_description = Some(field.description.clone());
|
||||||
|
parse(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if is_whole_col_parsed(csv_data, col_index) {
|
||||||
|
println!("col \"{}\" is parsed whole!", &col_index);
|
||||||
|
csv_data.parsed_cols.push(col_index);
|
||||||
|
}
|
||||||
|
if is_whole_table_parsed(&csv_data) {
|
||||||
|
csv_data.is_parsed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Communication {
|
pub enum Communication {
|
||||||
ValidateCreditentials(
|
ValidateCreditentials(
|
||||||
DBLoginData,
|
DBLoginData,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![cfg_attr(not(debug_assertions), deny(dead_code), deny(unused_variables))]
|
||||||
|
#![cfg_attr(debug_assertions, allow(dead_code), allow(unused_variables))]
|
||||||
mod backend;
|
mod backend;
|
||||||
mod ui;
|
mod ui;
|
||||||
use backend::backend_manager::BackendManger;
|
use backend::backend_manager::BackendManger;
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl CSQLWindow for DBLoginWindow {
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
_ui: &mut egui::Ui,
|
_ui: &mut egui::Ui,
|
||||||
_frame: &mut eframe::Frame,
|
_frame: &mut eframe::Frame,
|
||||||
) -> Option<ExitStatus> {
|
) -> Option<Result<ExitStatus, Box<dyn std::error::Error>>> {
|
||||||
egui::Window::new("MySQL Login")
|
egui::Window::new("MySQL Login")
|
||||||
.id(egui::Id::new("MySQL Login"))
|
.id(egui::Id::new("MySQL Login"))
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
|
@ -51,13 +51,11 @@ impl CSQLWindow for DBLoginWindow {
|
||||||
});
|
});
|
||||||
if let Some(result) = &self.are_creditentials_verified {
|
if let Some(result) = &self.are_creditentials_verified {
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => return Some(ExitStatus::Ok),
|
Ok(_) => return Some(Ok(ExitStatus::Ok)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Some(ExitStatus::Err(Box::from(<String as Into<
|
return Some(Err(Box::from(<String as Into<
|
||||||
Box<dyn std::error::Error>,
|
Box<dyn std::error::Error>,
|
||||||
>>::into(
|
>>::into(e.to_string()))))
|
||||||
e.to_string()
|
|
||||||
))))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use egui::{Context, Ui};
|
use egui::{Context, Ui};
|
||||||
use sqlx::mysql::MySqlQueryResult;
|
|
||||||
use std::error::Error;
|
|
||||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
|
@ -42,7 +40,7 @@ impl CSQLWindow for DBTransactionWindow {
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
) -> Option<ExitStatus> {
|
) -> Option<Result<ExitStatus, Box<dyn std::error::Error>>> {
|
||||||
egui::Window::new("Database Transactions")
|
egui::Window::new("Database Transactions")
|
||||||
.id(egui::Id::new("Database Transactions"))
|
.id(egui::Id::new("Database Transactions"))
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
|
@ -62,7 +60,7 @@ impl CSQLWindow for DBTransactionWindow {
|
||||||
});
|
});
|
||||||
|
|
||||||
if self.is_finished {
|
if self.is_finished {
|
||||||
return Some(ExitStatus::Ok);
|
return Some(Ok(ExitStatus::Ok));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -129,7 +127,7 @@ impl DBTransactionWindow {
|
||||||
.auto_shrink([false; 2])
|
.auto_shrink([false; 2])
|
||||||
.stick_to_bottom(true)
|
.stick_to_bottom(true)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
let mut table = egui_extras::TableBuilder::new(ui)
|
let table = egui_extras::TableBuilder::new(ui)
|
||||||
.striped(true)
|
.striped(true)
|
||||||
.resizable(true)
|
.resizable(true)
|
||||||
.cell_layout(egui::Layout::left_to_right(egui::Align::LEFT))
|
.cell_layout(egui::Layout::left_to_right(egui::Align::LEFT))
|
||||||
|
@ -155,7 +153,7 @@ impl DBTransactionWindow {
|
||||||
ui.strong("Result");
|
ui.strong("Result");
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.body(|mut body| {
|
.body(|body| {
|
||||||
body.rows(15.0, self.log_history.len(), |row_index, mut row| {
|
body.rows(15.0, self.log_history.len(), |row_index, mut row| {
|
||||||
let log = self.log_history.get(row_index).unwrap();
|
let log = self.log_history.get(row_index).unwrap();
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
|
@ -187,6 +185,6 @@ impl DBTransactionWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OptionsDBTransactionWindow {
|
pub struct OptionsDBTransactionWindow {
|
||||||
substitute_zero_dates_for_NULL: bool,
|
substitute_zero_dates_for_null: bool,
|
||||||
remove_id_field_from_insert: bool,
|
remove_id_field_from_insert: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,9 @@ pub struct SpreadSheetWindow {
|
||||||
csv_data_handle: Arc<Mutex<ImportedData>>,
|
csv_data_handle: Arc<Mutex<ImportedData>>,
|
||||||
db_table_data_handle: Arc<Mutex<Tables>>,
|
db_table_data_handle: Arc<Mutex<Tables>>,
|
||||||
current_table: Option<usize>,
|
current_table: Option<usize>,
|
||||||
should_export_to_db: bool,
|
return_status: Option<ExitStatus>,
|
||||||
debug_autoload_file_sent: bool,
|
debug_autoload_file_sent: bool,
|
||||||
|
is_table_description_request_sent: bool,
|
||||||
}
|
}
|
||||||
impl SpreadSheetWindow {
|
impl SpreadSheetWindow {
|
||||||
pub fn default(
|
pub fn default(
|
||||||
|
@ -29,7 +30,8 @@ impl SpreadSheetWindow {
|
||||||
db_table_data_handle,
|
db_table_data_handle,
|
||||||
current_table: None,
|
current_table: None,
|
||||||
debug_autoload_file_sent: false,
|
debug_autoload_file_sent: false,
|
||||||
should_export_to_db: false,
|
is_table_description_request_sent: false,
|
||||||
|
return_status: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,11 +41,11 @@ impl CSQLWindow for SpreadSheetWindow {
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
) -> Option<ExitStatus> {
|
) -> Option<Result<ExitStatus, Box<dyn std::error::Error>>> {
|
||||||
self.ui(ui, ctx);
|
self.ui(ui, ctx);
|
||||||
if self.should_export_to_db {
|
if let Some(return_status) = self.return_status {
|
||||||
self.should_export_to_db = false;
|
self.return_status = None;
|
||||||
return Some(ExitStatus::StartTransactionWindow);
|
return Some(Ok(return_status));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -57,15 +59,18 @@ impl SpreadSheetWindow {
|
||||||
} else {
|
} else {
|
||||||
is_csv_parsed = false;
|
is_csv_parsed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Program Menu */
|
/* Program Menu */
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.group(|ui| {});
|
if ui.button("Log into DB").clicked() {
|
||||||
|
self.return_status = Some(ExitStatus::StartLoginWindow);
|
||||||
|
}
|
||||||
|
ui.add_space(ui.available_width());
|
||||||
});
|
});
|
||||||
|
ui.separator();
|
||||||
/* CSV & DB menu */
|
/* CSV & DB menu */
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.columns(2, |uis| {
|
ui.columns(2, |uis| {
|
||||||
uis[0].group(|ui| {
|
uis[0].horizontal(|ui| {
|
||||||
if ui.button("Import file").clicked() {
|
if ui.button("Import file").clicked() {
|
||||||
self.open_file();
|
self.open_file();
|
||||||
}
|
}
|
||||||
|
@ -75,22 +80,24 @@ impl SpreadSheetWindow {
|
||||||
if ui.button("Save as...").clicked() {
|
if ui.button("Save as...").clicked() {
|
||||||
self.save_file();
|
self.save_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.add_space(ui.available_width());
|
||||||
|
ui.separator();
|
||||||
});
|
});
|
||||||
uis[1].group(|ui| {
|
uis[1].with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
ui.add_enabled_ui(is_csv_parsed, |ui| {
|
||||||
self.table_options(ui);
|
if ui.button("Append to DB").clicked() {
|
||||||
if ui.button("Import DB").clicked() {
|
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
ui.add_enabled_ui(is_csv_parsed, |ui| {
|
if ui.button("Save to DB").clicked() {
|
||||||
if ui.button("Save to DB").clicked() {
|
self.return_status = Some(ExitStatus::StartTransactionWindow);
|
||||||
self.should_export_to_db = true;
|
}
|
||||||
}
|
|
||||||
if ui.button("Append to DB").clicked() {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
if ui.button("Import DB").clicked() {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
self.table_options(ui);
|
||||||
|
ui.add_space(ui.available_width());
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -103,10 +110,11 @@ impl SpreadSheetWindow {
|
||||||
});
|
});
|
||||||
SpreadSheetWindow::preview_files_being_dropped(ctx);
|
SpreadSheetWindow::preview_files_being_dropped(ctx);
|
||||||
|
|
||||||
if self.current_table.is_none() {
|
if self.current_table.is_some() {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
egui::ScrollArea::horizontal().show(ui, |ui| {
|
egui::ScrollArea::horizontal().show(ui, |ui| {
|
||||||
self.table_builder(ui);
|
self.table_builder(ui)
|
||||||
|
.unwrap_or_else(|e| println!("Table un-intd, {:?}", e));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -142,45 +150,62 @@ impl SpreadSheetWindow {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn table_builder(&mut self, ui: &mut Ui) {
|
fn table_builder(&mut self, ui: &mut Ui) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if let Ok(csv_data) = &mut self.csv_data_handle.try_lock() {
|
if let Ok(csv_data) = &mut self.csv_data_handle.try_lock() {
|
||||||
if let Ok(db_table_data) = &mut self.db_table_data_handle.try_lock() {
|
if let Ok(db_table_data) = &mut self.db_table_data_handle.try_lock() {
|
||||||
//ref to all fields in curr db table
|
//ref to all fields in curr db table
|
||||||
let mut curr_db_table_fields: &mut Vec<TableField> = db_table_data
|
let mut curr_db_table_fields: &mut Vec<TableField> = match db_table_data
|
||||||
.tables
|
.tables
|
||||||
.get_mut(self.current_table.unwrap())
|
.get_mut(self.current_table.unwrap())
|
||||||
.unwrap()
|
.ok_or("no current table")?
|
||||||
.fields
|
.fields
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap();
|
.ok_or("no fields yet")
|
||||||
let mut table = TableBuilder::new(ui)
|
{
|
||||||
.striped(true)
|
Ok(val) => val,
|
||||||
.cell_layout(egui::Layout::left_to_right(egui::Align::Center));
|
Err(e) => {
|
||||||
|
if !self.is_table_description_request_sent {
|
||||||
for _i in 0..csv_data.data.cols() + 1 {
|
self.sender.try_send(Communication::GetTableDescription(
|
||||||
table = table.column(Column::auto().resizable(true).clip(false));
|
self.current_table.unwrap(),
|
||||||
|
))?;
|
||||||
|
self.is_table_description_request_sent = true;
|
||||||
|
}
|
||||||
|
return Err(Box::from(
|
||||||
|
<String as Into<Box<dyn std::error::Error>>>::into(e.to_string()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if csv_data.data.is_empty() {
|
||||||
|
return Err(<String as Into<Box<dyn std::error::Error>>>::into(
|
||||||
|
"no rows yet".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
/* If cols got prematched by name */
|
let table = TableBuilder::new(ui)
|
||||||
|
.striped(true)
|
||||||
|
.cell_layout(egui::Layout::left_to_right(egui::Align::Center))
|
||||||
|
/*First collumn for row actions */
|
||||||
|
.column(Column::auto().at_most(30.0).resizable(false).clip(false));
|
||||||
|
|
||||||
table
|
table
|
||||||
.column(Column::remainder())
|
.columns(
|
||||||
|
Column::auto().resizable(true).clip(false),
|
||||||
|
csv_data.data.cols(),
|
||||||
|
)
|
||||||
.min_scrolled_height(0.0)
|
.min_scrolled_height(0.0)
|
||||||
.header(20., |mut header| {
|
.header(20., |mut header| {
|
||||||
/* First Col for row mutators */
|
/* First Col for row mutators */
|
||||||
header.col(|ui|{
|
header.col(|ui|{
|
||||||
ui.add_space(45.0);
|
|
||||||
});
|
});
|
||||||
|
SpreadSheetWindow::add_header_cols(&mut header, csv_data,&mut curr_db_table_fields, &mut self.sender);
|
||||||
for i in 0..csv_data.data.cols() {
|
|
||||||
header.col(|ui| {
|
|
||||||
SpreadSheetWindow::add_header_col(ui,i, csv_data,&mut curr_db_table_fields, &mut self.sender);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.body(|body| {
|
.body(|body| {
|
||||||
body.rows(15., csv_data.data.rows() -1, |row_index, mut row| {
|
body.rows(15., csv_data.data.rows() - csv_data.are_headers as usize, |row_index, mut row| {
|
||||||
|
let headers_i_offset = csv_data.are_headers as usize;
|
||||||
|
row.col(|ui|{
|
||||||
|
if ui.button("x").clicked(){}
|
||||||
|
});
|
||||||
for curr_cell in
|
for curr_cell in
|
||||||
csv_data.data.iter_row_mut(row_index+1)
|
csv_data.data.iter_row_mut(row_index + headers_i_offset)
|
||||||
{
|
{
|
||||||
/* If cell is bound to a field, color it's bg according to is_parsed */
|
/* If cell is bound to a field, color it's bg according to is_parsed */
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
|
@ -214,68 +239,72 @@ impl SpreadSheetWindow {
|
||||||
} else {
|
} else {
|
||||||
ui.centered_and_justified(|ui| ui.heading("Drag and drop or Open a file..."));
|
ui.centered_and_justified(|ui| ui.heading("Drag and drop or Open a file..."));
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpreadSheetWindow {
|
impl SpreadSheetWindow {
|
||||||
pub fn add_header_col(
|
pub fn add_header_cols(
|
||||||
ui: &mut Ui,
|
header: &mut egui_extras::TableRow,
|
||||||
i: usize,
|
|
||||||
csv_data: &mut MutexGuard<ImportedData>,
|
csv_data: &mut MutexGuard<ImportedData>,
|
||||||
curr_db_table_fields: &mut Vec<TableField>,
|
curr_db_table_fields: &mut Vec<TableField>,
|
||||||
sender: &mut Sender<Communication>,
|
sender: &mut Sender<Communication>,
|
||||||
) {
|
) {
|
||||||
ui.vertical_centered_justified(|ui| {
|
for i in 0..csv_data.data.cols() {
|
||||||
if ui.button("x").clicked() {
|
header.col(|ui| {
|
||||||
todo!()
|
ui.vertical_centered_justified(|ui| {
|
||||||
}
|
if ui.button("x").clicked() {}
|
||||||
if csv_data.parsed_cols.contains(&i) {
|
if csv_data.parsed_cols.contains(&i) {
|
||||||
/* If the whole col is parsed, change header bg to green, else normal */
|
/* If the whole col is parsed, change header bg to green, else normal */
|
||||||
ui.style_mut().visuals.override_text_color = Some(egui::Color32::GREEN);
|
ui.style_mut().visuals.override_text_color = Some(egui::Color32::GREEN);
|
||||||
} else {
|
} else {
|
||||||
ui.style_mut().visuals.override_text_color = Some(egui::Color32::RED);
|
ui.style_mut().visuals.override_text_color = Some(egui::Color32::RED);
|
||||||
}
|
}
|
||||||
let mut combo_box: ComboBox;
|
let mut combo_box: ComboBox;
|
||||||
if csv_data.are_headers {
|
if csv_data.are_headers {
|
||||||
combo_box = ComboBox::new(i, csv_data.data.get(0, i).unwrap().data.clone());
|
combo_box = ComboBox::new(i, csv_data.data.get(0, i).unwrap().data.clone());
|
||||||
} else {
|
} else {
|
||||||
combo_box = ComboBox::new(i, "");
|
combo_box = ComboBox::new(i, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
//if any field is assinged to this combobox, show it's text, else "----"
|
//if any field is assinged to this combobox, show it's text, else "----"
|
||||||
if let Some(selected_field) = curr_db_table_fields
|
if let Some(selected_field) = curr_db_table_fields
|
||||||
.iter()
|
.iter()
|
||||||
.find(|field| field.mapped_to_col == Some(i))
|
.find(|field| field.mapped_to_col == Some(i))
|
||||||
{
|
|
||||||
combo_box = combo_box.selected_text(selected_field.description.field.clone());
|
|
||||||
} else {
|
|
||||||
combo_box = combo_box.selected_text("-----");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When a Field gets attached to Col, */
|
|
||||||
combo_box.show_ui(ui, |ui| {
|
|
||||||
for field in curr_db_table_fields.iter_mut() {
|
|
||||||
if ui
|
|
||||||
.selectable_value(
|
|
||||||
&mut field.mapped_to_col,
|
|
||||||
Some(i),
|
|
||||||
field.description.field.clone(),
|
|
||||||
)
|
|
||||||
.clicked()
|
|
||||||
{
|
{
|
||||||
match sender.try_send(Communication::TryParseCol(i)) {
|
combo_box =
|
||||||
Ok(_) => {
|
combo_box.selected_text(selected_field.description.field.clone());
|
||||||
for cel in csv_data.data.iter_col_mut(i) {
|
} else {
|
||||||
cel.curr_field_description = Some(field.description.clone());
|
combo_box = combo_box.selected_text("-----");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When a Field gets attached to Col, */
|
||||||
|
combo_box.show_ui(ui, |ui| {
|
||||||
|
for field in curr_db_table_fields.iter_mut() {
|
||||||
|
if ui
|
||||||
|
.selectable_value(
|
||||||
|
&mut field.mapped_to_col,
|
||||||
|
Some(i),
|
||||||
|
field.description.field.clone(),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
match sender.try_send(Communication::TryParseCol(i)) {
|
||||||
|
Ok(_) => {
|
||||||
|
for cel in csv_data.data.iter_col_mut(i) {
|
||||||
|
cel.curr_field_description =
|
||||||
|
Some(field.description.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => println!("failed sending parsecol request, {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => println!("failed sending parsecol request, {}", e),
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
ui.reset_style();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
ui.reset_style();
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_file(&mut self) {
|
pub fn save_file(&mut self) {
|
||||||
|
@ -296,19 +325,24 @@ impl SpreadSheetWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file(&mut self) {
|
pub fn open_file(&mut self) {
|
||||||
|
let final_path;
|
||||||
/*preloads file in debug */
|
/*preloads file in debug */
|
||||||
if cfg!(debug_assertions) && !self.debug_autoload_file_sent {
|
if cfg!(debug_assertions) && !self.debug_autoload_file_sent {
|
||||||
let path = std::path::PathBuf::from("/home/djkato/Dokumenty/csql/oc_product.csv");
|
final_path = std::path::PathBuf::from("/home/djkato/Dokumenty/csql/oc_product.csv");
|
||||||
println!(" * Preloading \"{:?}\"...", path);
|
println!(" * Preloading \"{:?}\"...", final_path);
|
||||||
self.debug_autoload_file_sent = true;
|
self.debug_autoload_file_sent = true;
|
||||||
}
|
} else {
|
||||||
if let Some(path) = rfd::FileDialog::new()
|
if let Some(path) = rfd::FileDialog::new()
|
||||||
.add_filter("Spreadsheets", &["csv"])
|
.add_filter("Spreadsheets", &["csv"])
|
||||||
.pick_file()
|
.pick_file()
|
||||||
{
|
{
|
||||||
|
final_path = path;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.sender
|
self.sender
|
||||||
.try_send(Communication::LoadImportFilePath(
|
.try_send(Communication::LoadImportFilePath(
|
||||||
path.display().to_string(),
|
final_path.display().to_string(),
|
||||||
))
|
))
|
||||||
.unwrap_or_else(|err| println!("failed to send loadimportpath, {}", err));
|
.unwrap_or_else(|err| println!("failed to send loadimportpath, {}", err));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,10 @@ use crate::ui::db_login_window::DBLoginWindow;
|
||||||
use crate::ui::table_window::SpreadSheetWindow;
|
use crate::ui::table_window::SpreadSheetWindow;
|
||||||
use eframe::{run_native, App, NativeOptions};
|
use eframe::{run_native, App, NativeOptions};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
use tokio::sync::mpsc::{channel, Sender};
|
||||||
use tokio::sync::oneshot;
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use super::db_transaction_window::DBTransactionWindow;
|
use super::db_transaction_window::DBTransactionWindow;
|
||||||
use super::{db_login_window, db_transaction_window};
|
|
||||||
|
|
||||||
pub fn create_ui(
|
pub fn create_ui(
|
||||||
sender: Sender<Communication>,
|
sender: Sender<Communication>,
|
||||||
|
@ -61,8 +59,11 @@ impl App for CSQL {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
if let Some(result) = self.spreadsheet_window.refresh(ctx, ui, frame) {
|
if let Some(result) = self.spreadsheet_window.refresh(ctx, ui, frame) {
|
||||||
match result {
|
match result {
|
||||||
ExitStatus::StartLoginWindow => self.should_open_transaction_window = true,
|
Ok(status) => match status {
|
||||||
ExitStatus::StartTransactionWindow => self.should_open_login_window = true,
|
ExitStatus::StartLoginWindow => self.should_open_transaction_window = true,
|
||||||
|
ExitStatus::StartTransactionWindow => self.should_open_login_window = true,
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -71,26 +72,37 @@ impl App for CSQL {
|
||||||
if let Some(db_login_window) = self.db_login_window.as_mut() {
|
if let Some(db_login_window) = self.db_login_window.as_mut() {
|
||||||
if let Some(result) = db_login_window.refresh(ctx, ui, frame) {
|
if let Some(result) = db_login_window.refresh(ctx, ui, frame) {
|
||||||
match result {
|
match result {
|
||||||
ExitStatus::Ok => {
|
Ok(status) => {
|
||||||
self.db_login_window = None;
|
self.db_login_window = None;
|
||||||
self.should_open_login_window = false;
|
self.should_open_login_window = false;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.db_login_window = Some(DBLoginWindow::default(self.sender.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.should_open_transaction_window {
|
if self.should_open_transaction_window {
|
||||||
if let Some(db_transaction_window) = self.db_transaction_window.as_mut() {
|
if let Some(db_transaction_window) = self.db_transaction_window.as_mut() {
|
||||||
if let Some(result) = db_transaction_window.refresh(ctx, ui, frame) {
|
if let Some(result) = db_transaction_window.refresh(ctx, ui, frame) {
|
||||||
match result {
|
match result {
|
||||||
ExitStatus::Ok => {
|
Ok(status) => {
|
||||||
self.db_transaction_window = None;
|
self.db_transaction_window = None;
|
||||||
self.should_open_transaction_window = false;
|
self.should_open_transaction_window = false;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if let Ok(db_table_data) = self.db_table_data_handle.try_lock() {
|
||||||
|
if let Some(cw_table_i) = db_table_data.current_working_table {
|
||||||
|
self.db_transaction_window = Some(DBTransactionWindow::default(
|
||||||
|
self.sender.clone(),
|
||||||
|
cw_table_i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -103,11 +115,11 @@ pub trait CSQLWindow {
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
) -> Option<ExitStatus>;
|
) -> Option<Result<ExitStatus, Box<dyn std::error::Error>>>;
|
||||||
}
|
}
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub enum ExitStatus {
|
pub enum ExitStatus {
|
||||||
StartTransactionWindow,
|
StartTransactionWindow,
|
||||||
StartLoginWindow,
|
StartLoginWindow,
|
||||||
Ok,
|
Ok,
|
||||||
Err(Box<dyn std::error::Error>),
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue