Refactor import_csv callbacks
This commit is contained in:
parent
de42499444
commit
8a3bbc8b92
|
@ -0,0 +1,308 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use js_sys::Array;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use regex::Regex;
|
||||||
|
use wasm_bindgen::{prelude::*, JsCast, JsValue};
|
||||||
|
use web_sys::{
|
||||||
|
Blob, FileReader, HtmlAnchorElement, HtmlButtonElement, HtmlDialogElement, HtmlElement,
|
||||||
|
HtmlFormElement, HtmlInputElement, HtmlOptionElement, HtmlSelectElement, Url,
|
||||||
|
};
|
||||||
|
use yew::prelude::*;
|
||||||
|
use yewdux::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::states::{CurrentTransfer, MainState};
|
||||||
|
use crate::components::transfer_menu::letters_to_num;
|
||||||
|
|
||||||
|
use crate::data::transfer::Transfer;
|
||||||
|
use crate::data::transfer_region::{Region, TransferRegion};
|
||||||
|
|
||||||
|
use crate::data::csv::{state_to_csv, TransferRecord};
|
||||||
|
|
||||||
|
use super::main_window_callbacks::create_close_button;
|
||||||
|
|
||||||
|
type NoParamsCallback = Box<dyn Fn(()) -> ()>;
|
||||||
|
|
||||||
|
pub fn import_transfer_csv_input_callback(
|
||||||
|
main_dispatch: Dispatch<MainState>,
|
||||||
|
modal: HtmlDialogElement,
|
||||||
|
) -> Closure<dyn FnMut(Event)> {
|
||||||
|
Closure::<dyn FnMut(_)>::new(move |e: Event| {
|
||||||
|
if let Some(input) = e.current_target() {
|
||||||
|
let input = input
|
||||||
|
.dyn_into::<HtmlInputElement>()
|
||||||
|
.expect("We know this is an input.");
|
||||||
|
if let Some(files) = input.files() {
|
||||||
|
if let Some(file) = files.get(0) {
|
||||||
|
let fr = web_sys::FileReader::new().unwrap();
|
||||||
|
fr.read_as_text(&file).unwrap();
|
||||||
|
let fr1 = fr.clone(); // Clone to avoid outliving closure
|
||||||
|
let main_dispatch = main_dispatch.clone(); // Clone to satisfy FnMut
|
||||||
|
// trait
|
||||||
|
let modal = modal.clone();
|
||||||
|
let onload = import_transfer_csv_onload_callback(main_dispatch, fr1, modal);
|
||||||
|
fr.set_onload(Some(onload.as_ref().unchecked_ref()));
|
||||||
|
onload.forget(); // Magic (don't touch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn import_transfer_csv_callback(main_dispatch: Dispatch<MainState>) -> Callback<MouseEvent> {
|
||||||
|
Callback::from(move |_| {
|
||||||
|
let window = web_sys::window().unwrap();
|
||||||
|
let document = window.document().unwrap();
|
||||||
|
let body = document.body().unwrap();
|
||||||
|
let modal = document
|
||||||
|
.create_element("dialog")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlDialogElement>()
|
||||||
|
.unwrap();
|
||||||
|
modal.set_text_content(Some("Import File:"));
|
||||||
|
let onclose_callback = {
|
||||||
|
let modal = modal.clone();
|
||||||
|
Closure::<dyn FnMut(_)>::new(move |_: Event| {
|
||||||
|
modal.remove();
|
||||||
|
})
|
||||||
|
};
|
||||||
|
modal.set_onclose(Some(onclose_callback.as_ref().unchecked_ref()));
|
||||||
|
|
||||||
|
let close_button = create_close_button(&onclose_callback);
|
||||||
|
onclose_callback.forget();
|
||||||
|
modal.append_child(&close_button).unwrap();
|
||||||
|
|
||||||
|
let form = document
|
||||||
|
.create_element("form")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlFormElement>()
|
||||||
|
.unwrap();
|
||||||
|
let input = document
|
||||||
|
.create_element("input")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlInputElement>()
|
||||||
|
.unwrap();
|
||||||
|
input.set_type("file");
|
||||||
|
input.set_accept(".csv");
|
||||||
|
form.append_child(&input).unwrap();
|
||||||
|
|
||||||
|
let input_callback = {
|
||||||
|
let main_dispatch = main_dispatch.clone();
|
||||||
|
let modal = modal.clone();
|
||||||
|
import_transfer_csv_input_callback(main_dispatch, modal)
|
||||||
|
};
|
||||||
|
input.set_onchange(Some(input_callback.as_ref().unchecked_ref()));
|
||||||
|
input_callback.forget(); // Magic straight from the docs, don't touch :(
|
||||||
|
|
||||||
|
modal.append_child(&form).unwrap();
|
||||||
|
body.append_child(&modal).unwrap();
|
||||||
|
modal.show_modal().unwrap();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn import_transfer_csv_onload_callback(
|
||||||
|
main_dispatch: Dispatch<MainState>,
|
||||||
|
file_reader: FileReader,
|
||||||
|
modal: HtmlDialogElement,
|
||||||
|
) -> Closure<dyn FnMut(Event)> {
|
||||||
|
Closure::<dyn FnMut(_)>::new(move |_: Event| {
|
||||||
|
if let Some(value) = &file_reader.result().ok().and_then(|v| v.as_string()) {
|
||||||
|
let mut rdr = csv::Reader::from_reader(value.as_bytes());
|
||||||
|
let mut records = Vec::new();
|
||||||
|
for record in rdr.deserialize::<crate::data::csv::TransferRecord>() {
|
||||||
|
match record {
|
||||||
|
Ok(r) => {
|
||||||
|
//log::debug!("{:?}", r);
|
||||||
|
records.push(r);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::debug!("{:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut sources: HashSet<String> = HashSet::new();
|
||||||
|
let mut destinations: HashSet<String> = HashSet::new();
|
||||||
|
for record in records.iter() {
|
||||||
|
sources.insert(record.source_plate.clone());
|
||||||
|
destinations.insert(record.destination_plate.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let window = web_sys::window().unwrap();
|
||||||
|
let document = window.document().unwrap();
|
||||||
|
let form = document
|
||||||
|
.create_element("form")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlFormElement>()
|
||||||
|
.unwrap();
|
||||||
|
let from_source = document
|
||||||
|
.create_element("select")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlSelectElement>()
|
||||||
|
.unwrap();
|
||||||
|
for source in sources {
|
||||||
|
let option = document
|
||||||
|
.create_element("option")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlOptionElement>()
|
||||||
|
.unwrap();
|
||||||
|
option.set_value(&source);
|
||||||
|
option.set_text(&source);
|
||||||
|
from_source.append_child(&option).unwrap();
|
||||||
|
}
|
||||||
|
let to_source = document
|
||||||
|
.create_element("select")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlSelectElement>()
|
||||||
|
.unwrap();
|
||||||
|
for source in &main_dispatch.get().source_plates {
|
||||||
|
let option = document
|
||||||
|
.create_element("option")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlOptionElement>()
|
||||||
|
.unwrap();
|
||||||
|
option.set_value(&source.name);
|
||||||
|
option.set_text(&source.name);
|
||||||
|
to_source.append_child(&option).unwrap();
|
||||||
|
}
|
||||||
|
let from_dest = document
|
||||||
|
.create_element("select")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlSelectElement>()
|
||||||
|
.unwrap();
|
||||||
|
for dest in destinations {
|
||||||
|
let option = document
|
||||||
|
.create_element("option")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlOptionElement>()
|
||||||
|
.unwrap();
|
||||||
|
option.set_value(&dest);
|
||||||
|
option.set_text(&dest);
|
||||||
|
from_dest.append_child(&option).unwrap();
|
||||||
|
}
|
||||||
|
let to_dest = document
|
||||||
|
.create_element("select")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlSelectElement>()
|
||||||
|
.unwrap();
|
||||||
|
for dest in &main_dispatch.get().destination_plates {
|
||||||
|
let option = document
|
||||||
|
.create_element("option")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlOptionElement>()
|
||||||
|
.unwrap();
|
||||||
|
option.set_value(&dest.name);
|
||||||
|
option.set_text(&dest.name);
|
||||||
|
to_dest.append_child(&option).unwrap();
|
||||||
|
}
|
||||||
|
let submit = document
|
||||||
|
.create_element("button")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlButtonElement>()
|
||||||
|
.unwrap();
|
||||||
|
submit.set_value("Submit");
|
||||||
|
submit.set_inner_text("Submit");
|
||||||
|
let submit_callback = {
|
||||||
|
let main_dispatch = main_dispatch.clone();
|
||||||
|
let from_source = from_source.clone();
|
||||||
|
let to_source = to_source.clone();
|
||||||
|
let from_dest = from_dest.clone();
|
||||||
|
let to_dest = to_dest.clone();
|
||||||
|
import_transfer_csv_submit_callback(
|
||||||
|
main_dispatch,
|
||||||
|
from_source,
|
||||||
|
to_source,
|
||||||
|
from_dest,
|
||||||
|
to_dest,
|
||||||
|
records,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
submit.set_onclick(Some(submit_callback.as_ref().unchecked_ref()));
|
||||||
|
submit_callback.forget();
|
||||||
|
|
||||||
|
form.append_child(&from_source).unwrap();
|
||||||
|
form.append_child(&to_source).unwrap();
|
||||||
|
form.append_child(&from_dest).unwrap();
|
||||||
|
form.append_child(&to_dest).unwrap();
|
||||||
|
modal.append_child(&submit).unwrap();
|
||||||
|
modal.append_child(&form).unwrap();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn import_transfer_csv_submit_callback(
|
||||||
|
main_dispatch: Dispatch<MainState>,
|
||||||
|
from_source: HtmlSelectElement,
|
||||||
|
to_source: HtmlSelectElement,
|
||||||
|
from_dest: HtmlSelectElement,
|
||||||
|
to_dest: HtmlSelectElement,
|
||||||
|
records: Vec<TransferRecord>,
|
||||||
|
) -> Closure<dyn FnMut(Event)> {
|
||||||
|
Closure::<dyn FnMut(_)>::new(move |_: Event| {
|
||||||
|
let from_source = from_source.value();
|
||||||
|
let to_source = to_source.value();
|
||||||
|
let from_dest = from_dest.value();
|
||||||
|
let to_dest = to_dest.value();
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref REGEX: Regex = Regex::new(r"([A-Z]+)(\d+)").unwrap();
|
||||||
|
}
|
||||||
|
let records: Vec<((u8, u8), (u8, u8))> = records
|
||||||
|
.iter()
|
||||||
|
.filter(|record| record.source_plate == from_source)
|
||||||
|
.filter(|record| record.destination_plate == from_dest)
|
||||||
|
.map(|record| {
|
||||||
|
let c1 = REGEX.captures(&record.source_well).unwrap();
|
||||||
|
let c2 = REGEX.captures(&record.destination_well).unwrap();
|
||||||
|
log::debug!("{} {}", &record.source_well, &record.destination_well);
|
||||||
|
log::debug!("{},{} {},{}", &c1[1], &c1[2], &c2[1], &c2[2]);
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
letters_to_num(&c1[1]).unwrap(),
|
||||||
|
c1[2].parse::<u8>().unwrap(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
letters_to_num(&c2[1]).unwrap(),
|
||||||
|
c2[2].parse::<u8>().unwrap(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let spi = main_dispatch
|
||||||
|
.get()
|
||||||
|
.source_plates
|
||||||
|
.iter()
|
||||||
|
.find(|src| src.name == to_source)
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let dpi = main_dispatch
|
||||||
|
.get()
|
||||||
|
.destination_plates
|
||||||
|
.iter()
|
||||||
|
.find(|dest| dest.name == to_dest)
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let custom_region = Region::new_custom(&records);
|
||||||
|
let transfer_region = TransferRegion {
|
||||||
|
source_region: custom_region.clone(),
|
||||||
|
dest_region: custom_region,
|
||||||
|
interleave_source: (1, 1),
|
||||||
|
interleave_dest: (1, 1),
|
||||||
|
source_plate: spi.plate,
|
||||||
|
dest_plate: dpi.plate,
|
||||||
|
};
|
||||||
|
|
||||||
|
let transfer = Transfer::new(spi, dpi, transfer_region, "Custom Transfer".to_string());
|
||||||
|
main_dispatch.reduce_mut(|state| {
|
||||||
|
state.transfers.push(transfer);
|
||||||
|
state.selected_transfer = state
|
||||||
|
.transfers
|
||||||
|
.last()
|
||||||
|
.expect("An element should have just been added")
|
||||||
|
.get_uuid();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ use crate::data::csv::{state_to_csv, TransferRecord};
|
||||||
|
|
||||||
type NoParamsCallback = Box<dyn Fn(()) -> ()>;
|
type NoParamsCallback = Box<dyn Fn(()) -> ()>;
|
||||||
|
|
||||||
fn create_close_button(close: &Closure<dyn FnMut(Event)>) -> HtmlElement {
|
pub fn create_close_button(close: &Closure<dyn FnMut(Event)>) -> HtmlElement {
|
||||||
let document = web_sys::window().unwrap().document().unwrap();
|
let document = web_sys::window().unwrap().document().unwrap();
|
||||||
let close_button = document
|
let close_button = document
|
||||||
.create_element("button")
|
.create_element("button")
|
||||||
|
@ -216,287 +216,10 @@ pub fn import_json_button_callback(main_dispatch: Dispatch<MainState>) -> Callba
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_transfer_csv_submit_callback(
|
pub use super::import_csv_callbacks::import_transfer_csv_callback;
|
||||||
main_dispatch: Dispatch<MainState>,
|
|
||||||
from_source: HtmlSelectElement,
|
|
||||||
to_source: HtmlSelectElement,
|
|
||||||
from_dest: HtmlSelectElement,
|
|
||||||
to_dest: HtmlSelectElement,
|
|
||||||
records: Vec<TransferRecord>,
|
|
||||||
) -> Closure<dyn FnMut(Event)> {
|
|
||||||
Closure::<dyn FnMut(_)>::new(move |_: Event| {
|
|
||||||
let from_source = from_source.value();
|
|
||||||
let to_source = to_source.value();
|
|
||||||
let from_dest = from_dest.value();
|
|
||||||
let to_dest = to_dest.value();
|
|
||||||
|
|
||||||
lazy_static! {
|
pub use super::import_csv_callbacks::import_transfer_csv_submit_callback;
|
||||||
static ref REGEX: Regex = Regex::new(r"([A-Z]+)(\d+)").unwrap();
|
|
||||||
}
|
|
||||||
let records: Vec<((u8, u8), (u8, u8))> = records
|
|
||||||
.iter()
|
|
||||||
.filter(|record| record.source_plate == from_source)
|
|
||||||
.filter(|record| record.destination_plate == from_dest)
|
|
||||||
.map(|record| {
|
|
||||||
let c1 = REGEX.captures(&record.source_well).unwrap();
|
|
||||||
let c2 = REGEX.captures(&record.destination_well).unwrap();
|
|
||||||
log::debug!("{} {}", &record.source_well, &record.destination_well);
|
|
||||||
log::debug!("{},{} {},{}", &c1[1], &c1[2], &c2[1], &c2[2]);
|
|
||||||
|
|
||||||
(
|
pub use super::import_csv_callbacks::import_transfer_csv_onload_callback;
|
||||||
(
|
|
||||||
letters_to_num(&c1[1]).unwrap(),
|
|
||||||
c1[2].parse::<u8>().unwrap(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
letters_to_num(&c2[1]).unwrap(),
|
|
||||||
c2[2].parse::<u8>().unwrap(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let spi = main_dispatch
|
|
||||||
.get()
|
|
||||||
.source_plates
|
|
||||||
.iter()
|
|
||||||
.find(|src| src.name == to_source)
|
|
||||||
.unwrap()
|
|
||||||
.clone();
|
|
||||||
let dpi = main_dispatch
|
|
||||||
.get()
|
|
||||||
.destination_plates
|
|
||||||
.iter()
|
|
||||||
.find(|dest| dest.name == to_dest)
|
|
||||||
.unwrap()
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
let custom_region = Region::new_custom(&records);
|
|
||||||
let transfer_region = TransferRegion {
|
|
||||||
source_region: custom_region.clone(),
|
|
||||||
dest_region: custom_region,
|
|
||||||
interleave_source: (1, 1),
|
|
||||||
interleave_dest: (1, 1),
|
|
||||||
source_plate: spi.plate,
|
|
||||||
dest_plate: dpi.plate,
|
|
||||||
};
|
|
||||||
|
|
||||||
let transfer = Transfer::new(spi, dpi, transfer_region, "Custom Transfer".to_string());
|
|
||||||
main_dispatch.reduce_mut(|state| {
|
|
||||||
state.transfers.push(transfer);
|
|
||||||
state.selected_transfer = state
|
|
||||||
.transfers
|
|
||||||
.last()
|
|
||||||
.expect("An element should have just been added")
|
|
||||||
.get_uuid();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn import_transfer_csv_onload_callback(
|
|
||||||
main_dispatch: Dispatch<MainState>,
|
|
||||||
file_reader: FileReader,
|
|
||||||
modal: HtmlDialogElement,
|
|
||||||
) -> Closure<dyn FnMut(Event)> {
|
|
||||||
Closure::<dyn FnMut(_)>::new(move |_: Event| {
|
|
||||||
if let Some(value) = &file_reader.result().ok().and_then(|v| v.as_string()) {
|
|
||||||
let mut rdr = csv::Reader::from_reader(value.as_bytes());
|
|
||||||
let mut records = Vec::new();
|
|
||||||
for record in rdr.deserialize::<crate::data::csv::TransferRecord>() {
|
|
||||||
match record {
|
|
||||||
Ok(r) => {
|
|
||||||
//log::debug!("{:?}", r);
|
|
||||||
records.push(r);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
log::debug!("{:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut sources: HashSet<String> = HashSet::new();
|
|
||||||
let mut destinations: HashSet<String> = HashSet::new();
|
|
||||||
for record in records.iter() {
|
|
||||||
sources.insert(record.source_plate.clone());
|
|
||||||
destinations.insert(record.destination_plate.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let window = web_sys::window().unwrap();
|
|
||||||
let document = window.document().unwrap();
|
|
||||||
let form = document
|
|
||||||
.create_element("form")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlFormElement>()
|
|
||||||
.unwrap();
|
|
||||||
let from_source = document
|
|
||||||
.create_element("select")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlSelectElement>()
|
|
||||||
.unwrap();
|
|
||||||
for source in sources {
|
|
||||||
let option = document
|
|
||||||
.create_element("option")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlOptionElement>()
|
|
||||||
.unwrap();
|
|
||||||
option.set_value(&source);
|
|
||||||
option.set_text(&source);
|
|
||||||
from_source.append_child(&option).unwrap();
|
|
||||||
}
|
|
||||||
let to_source = document
|
|
||||||
.create_element("select")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlSelectElement>()
|
|
||||||
.unwrap();
|
|
||||||
for source in &main_dispatch.get().source_plates {
|
|
||||||
let option = document
|
|
||||||
.create_element("option")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlOptionElement>()
|
|
||||||
.unwrap();
|
|
||||||
option.set_value(&source.name);
|
|
||||||
option.set_text(&source.name);
|
|
||||||
to_source.append_child(&option).unwrap();
|
|
||||||
}
|
|
||||||
let from_dest = document
|
|
||||||
.create_element("select")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlSelectElement>()
|
|
||||||
.unwrap();
|
|
||||||
for dest in destinations {
|
|
||||||
let option = document
|
|
||||||
.create_element("option")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlOptionElement>()
|
|
||||||
.unwrap();
|
|
||||||
option.set_value(&dest);
|
|
||||||
option.set_text(&dest);
|
|
||||||
from_dest.append_child(&option).unwrap();
|
|
||||||
}
|
|
||||||
let to_dest = document
|
|
||||||
.create_element("select")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlSelectElement>()
|
|
||||||
.unwrap();
|
|
||||||
for dest in &main_dispatch.get().destination_plates {
|
|
||||||
let option = document
|
|
||||||
.create_element("option")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlOptionElement>()
|
|
||||||
.unwrap();
|
|
||||||
option.set_value(&dest.name);
|
|
||||||
option.set_text(&dest.name);
|
|
||||||
to_dest.append_child(&option).unwrap();
|
|
||||||
}
|
|
||||||
let submit = document
|
|
||||||
.create_element("button")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlButtonElement>()
|
|
||||||
.unwrap();
|
|
||||||
submit.set_value("Submit");
|
|
||||||
submit.set_inner_text("Submit");
|
|
||||||
let submit_callback = {
|
|
||||||
let main_dispatch = main_dispatch.clone();
|
|
||||||
let from_source = from_source.clone();
|
|
||||||
let to_source = to_source.clone();
|
|
||||||
let from_dest = from_dest.clone();
|
|
||||||
let to_dest = to_dest.clone();
|
|
||||||
import_transfer_csv_submit_callback(
|
|
||||||
main_dispatch,
|
|
||||||
from_source,
|
|
||||||
to_source,
|
|
||||||
from_dest,
|
|
||||||
to_dest,
|
|
||||||
records,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
submit.set_onclick(Some(submit_callback.as_ref().unchecked_ref()));
|
|
||||||
submit_callback.forget();
|
|
||||||
|
|
||||||
form.append_child(&from_source).unwrap();
|
|
||||||
form.append_child(&to_source).unwrap();
|
|
||||||
form.append_child(&from_dest).unwrap();
|
|
||||||
form.append_child(&to_dest).unwrap();
|
|
||||||
modal.append_child(&submit).unwrap();
|
|
||||||
modal.append_child(&form).unwrap();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn import_transfer_csv_input_callback(
|
|
||||||
main_dispatch: Dispatch<MainState>,
|
|
||||||
modal: HtmlDialogElement,
|
|
||||||
) -> Closure<dyn FnMut(Event)> {
|
|
||||||
Closure::<dyn FnMut(_)>::new(move |e: Event| {
|
|
||||||
if let Some(input) = e.current_target() {
|
|
||||||
let input = input
|
|
||||||
.dyn_into::<HtmlInputElement>()
|
|
||||||
.expect("We know this is an input.");
|
|
||||||
if let Some(files) = input.files() {
|
|
||||||
if let Some(file) = files.get(0) {
|
|
||||||
let fr = web_sys::FileReader::new().unwrap();
|
|
||||||
fr.read_as_text(&file).unwrap();
|
|
||||||
let fr1 = fr.clone(); // Clone to avoid outliving closure
|
|
||||||
let main_dispatch = main_dispatch.clone(); // Clone to satisfy FnMut
|
|
||||||
// trait
|
|
||||||
let modal = modal.clone();
|
|
||||||
let onload = import_transfer_csv_onload_callback(main_dispatch, fr1, modal);
|
|
||||||
fr.set_onload(Some(onload.as_ref().unchecked_ref()));
|
|
||||||
onload.forget(); // Magic (don't touch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn import_transfer_csv_callback(main_dispatch: Dispatch<MainState>) -> Callback<MouseEvent> {
|
|
||||||
Callback::from(move |_| {
|
|
||||||
let window = web_sys::window().unwrap();
|
|
||||||
let document = window.document().unwrap();
|
|
||||||
let body = document.body().unwrap();
|
|
||||||
let modal = document
|
|
||||||
.create_element("dialog")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlDialogElement>()
|
|
||||||
.unwrap();
|
|
||||||
modal.set_text_content(Some("Import File:"));
|
|
||||||
let onclose_callback = {
|
|
||||||
let modal = modal.clone();
|
|
||||||
Closure::<dyn FnMut(_)>::new(move |_: Event| {
|
|
||||||
modal.remove();
|
|
||||||
})
|
|
||||||
};
|
|
||||||
modal.set_onclose(Some(onclose_callback.as_ref().unchecked_ref()));
|
|
||||||
|
|
||||||
let close_button = create_close_button(&onclose_callback);
|
|
||||||
onclose_callback.forget();
|
|
||||||
modal.append_child(&close_button).unwrap();
|
|
||||||
|
|
||||||
let form = document
|
|
||||||
.create_element("form")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlFormElement>()
|
|
||||||
.unwrap();
|
|
||||||
let input = document
|
|
||||||
.create_element("input")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<HtmlInputElement>()
|
|
||||||
.unwrap();
|
|
||||||
input.set_type("file");
|
|
||||||
input.set_accept(".csv");
|
|
||||||
form.append_child(&input).unwrap();
|
|
||||||
|
|
||||||
let input_callback = {
|
|
||||||
let main_dispatch = main_dispatch.clone();
|
|
||||||
let modal = modal.clone();
|
|
||||||
import_transfer_csv_input_callback(main_dispatch, modal)
|
|
||||||
};
|
|
||||||
input.set_onchange(Some(input_callback.as_ref().unchecked_ref()));
|
|
||||||
input_callback.forget(); // Magic straight from the docs, don't touch :(
|
|
||||||
|
|
||||||
modal.append_child(&form).unwrap();
|
|
||||||
body.append_child(&modal).unwrap();
|
|
||||||
modal.show_modal().unwrap();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pub use super::import_csv_callbacks::import_transfer_csv_input_callback;
|
||||||
|
|
|
@ -2,3 +2,4 @@ pub mod main_window_callbacks;
|
||||||
pub mod new_plate_dialog_callbacks;
|
pub mod new_plate_dialog_callbacks;
|
||||||
pub mod transfer_menu_callbacks;
|
pub mod transfer_menu_callbacks;
|
||||||
pub mod tree_callbacks;
|
pub mod tree_callbacks;
|
||||||
|
mod import_csv_callbacks;
|
||||||
|
|
Loading…
Reference in New Issue