mod row_selector;
mod symbol_pairs;
mod symbol_pairs_item;
mod symbol_selector;
use std::collections::HashMap;
use std::rc::Rc;
use itertools::Itertools;
use yew::{Callback, Html, Properties, html};
use crate::components::column_settings_sidebar::style_tab::symbol::symbol_pairs::PairsList;
use crate::components::filter_dropdown::{FilterDropDownElement, FilterDropDownPortal};
use crate::components::style::LocalStyle;
use crate::config::{ColumnConfigValueUpdate, KeyValueOpts, SymbolKVPair};
use crate::css;
use crate::session::Session;
#[derive(Properties, PartialEq, Clone)]
pub struct SymbolAttrProps {
pub session: Session,
pub column_name: String,
pub restored_config: Option<HashMap<String, String>>,
pub on_change: Callback<ColumnConfigValueUpdate>,
pub default_config: KeyValueOpts,
pub selected_theme: Option<String>,
}
impl SymbolAttrProps {
pub fn next_default_symbol(&self, pairs_len: usize) -> String {
let values = &self.default_config.values;
values.get(pairs_len % values.len()).cloned().unwrap()
}
}
pub enum SymbolAttrMsg {
UpdatePairs(Vec<SymbolKVPair>),
}
pub struct SymbolStyle {
pairs: Vec<SymbolKVPair>,
row_dropdown: Rc<FilterDropDownElement>,
}
impl yew::Component for SymbolStyle {
type Message = SymbolAttrMsg;
type Properties = SymbolAttrProps;
fn create(ctx: &yew::Context<Self>) -> Self {
let pairs = ctx
.props()
.restored_config
.as_ref()
.map(|restored_config| {
let mut pairs = restored_config
.iter()
.map(|(key, value)| SymbolKVPair::new(Some(key.to_owned()), value.to_owned()))
.collect_vec();
pairs.push(SymbolKVPair::new(
None,
ctx.props().next_default_symbol(pairs.len()),
));
pairs
})
.unwrap_or_default();
let row_dropdown = Rc::new(FilterDropDownElement::new(ctx.props().session.clone()));
Self {
pairs,
row_dropdown,
}
}
fn update(&mut self, ctx: &yew::Context<Self>, msg: Self::Message) -> bool {
match msg {
SymbolAttrMsg::UpdatePairs(mut new_pairs) => {
let symbols = new_pairs
.clone()
.into_iter()
.filter_map(|pair| Some((pair.key?, pair.value)))
.collect::<HashMap<_, _>>();
let update = Some(symbols).filter(|x| !x.is_empty());
ctx.props()
.on_change
.emit(ColumnConfigValueUpdate::Symbols(update));
let has_last_key = new_pairs
.last()
.map(|pair| pair.key.is_some())
.unwrap_or_default();
if has_last_key {
let val = ctx.props().next_default_symbol(new_pairs.len());
new_pairs.push(SymbolKVPair::new(None, val))
}
self.pairs = new_pairs;
true
},
}
}
fn view(&self, ctx: &yew::Context<Self>) -> Html {
let update_pairs = ctx.link().callback(SymbolAttrMsg::UpdatePairs);
html! {
<>
<LocalStyle href={css!("column-symbol-attributes")} />
<PairsList
title="Symbols"
id="attributes-symbols"
pairs={self.pairs.clone()}
row_dropdown={self.row_dropdown.clone()}
column_name={ctx.props().column_name.clone()}
values={Rc::new(ctx.props().default_config.values.clone())}
{update_pairs}
/>
<FilterDropDownPortal
element={(*self.row_dropdown).clone()}
theme={ctx.props().selected_theme.clone().unwrap_or_default()}
/>
</>
}
}
}