use leptos::prelude::{ClassAttribute, For, Get, IntoAny, OnAttribute, Show};
use leptos::prelude::{ElementChild, RwSignal, Signal};
use std::fmt::Debug;
use std::{hash::Hash, sync::Arc};
use leptos::{IntoView, view};
use leptos_struct_table::*;
pub trait GroupRow<Column> {
fn group_info(&self) -> &GroupingInfo<Column>;
}
#[allow(unused_variables, non_snake_case)]
pub fn GroupTableRowRenderer<Row, Column>(
class: Signal<String>,
row: RwSignal<Row>,
index: usize,
selected: Signal<bool>,
on_select: EventHandler<web_sys::MouseEvent>,
columns: RwSignal<Vec<Column>>,
) -> impl IntoView
where
Row: TableRow<Column> + Debug + Clone + Send + Sync + GroupRow<Column> + 'static,
Column: Eq + Hash + Copy + Clone + Send + Sync + 'static,
{
leptos::view! {
<tr class=class on:click=move |mouse_event| on_select.run(mouse_event)>
<For
each=move || columns.get().into_iter()
key=|column| *column
children=move |column| {
let temp_row = row.get();
let grouping_info = temp_row.group_info();
if !grouping_info.grouped_by.is_empty() {
let class = if grouping_info.grouped_by.contains(&column) && grouping_info.row_index == 0 {
"font-bold".into()
} else {
String::new()
};
if grouping_info.nb_entries > 1 {
if grouping_info.row_index == 0 {
if grouping_info.grouped_by.contains(&column) {
return Row::cell_renderer_for_column(row, column, class).into_any()
}
} else {
if !grouping_info.grouped_by.contains(&column) ||
grouping_info.grouped_by.len() == Row::columns().len() {
return Row::cell_renderer_for_column(row, column, class).into_any()
}
}
} else {
return Row::cell_renderer_for_column(row, column, class).into_any()
}
} else {
return Row::cell_renderer_for_column(row, column, String::new()).into_any()
}
view!{ <td/> }.into_any()
}>
</For>
</tr>
<Show
when=move || {
let temp_row = row.get();
let grouping_info = temp_row.group_info();
grouping_info.row_index == 0 &&
grouping_info.nb_entries > 1 &&
!grouping_info.grouped_by.is_empty() &&
grouping_info.grouped_by.len() != Row::columns().len()
}
fallback=|| ()
>
<tr class=class>
<For
each=move || columns.get().into_iter()
key=|column| *column
children=move |column| {
let temp_row = row.get();
let grouping_info = temp_row.group_info();
if !grouping_info.grouped_by.contains(&column) {
return Row::cell_renderer_for_column(row, column, String::new()).into_any()
}
view!{ <td/> }.into_any()
}>
</For>
</tr>
</Show>
}
}
#[derive(Debug, Clone)]
pub struct GroupingInfo<Column> {
pub row_index: u32,
pub nb_entries: u32,
pub grouped_by: Arc<Vec<Column>>,
}
impl<T> Default for GroupingInfo<T> {
fn default() -> Self {
Self {
row_index: Default::default(),
nb_entries: Default::default(),
grouped_by: Default::default(),
}
}
}