use std::sync::Arc;
use derive_where::derive_where;
use topcoat::icon::IconData;
use super::Table;
use crate::{Reads, Text};
#[derive_where(Clone)]
pub struct RowLink<M> {
pub(crate) label: Text,
url: crate::column::ReadFn<M, Option<String>>,
pub(crate) icon: Option<IconData>,
pub(crate) new_tab: bool,
pub(super) reads: Option<Reads<M>>,
bare: bool,
}
impl<M> RowLink<M> {
pub fn new(
label: impl Into<Text>,
url: impl Fn(&M) -> Option<String> + Send + Sync + 'static,
) -> Self {
Self {
label: label.into(),
url: Arc::new(url),
icon: None,
new_tab: false,
reads: None,
bare: false,
}
}
pub fn icon(mut self, icon: IconData) -> Self {
self.icon = Some(icon);
self
}
pub fn new_tab(mut self) -> Self {
self.new_tab = true;
self
}
pub fn reading(mut self, reads: Reads<M>) -> Self {
self.reads = Some(reads);
self
}
pub(crate) fn url_of(&self, row: &M) -> Option<String> {
(self.url)(row).filter(|url| crate::column::link_href(url).is_some())
}
}
impl<M> Table<M> {
pub fn row_link(mut self, link: RowLink<M>) -> Self {
self.row_links.push(link);
self
}
pub(crate) fn row_links(&self) -> &[RowLink<M>] {
&self.row_links
}
pub(crate) fn row_link_reads_row(&self) -> bool {
self.row_links.iter().any(|link| !link.bare)
}
pub(super) fn bare_row_links(&mut self, bare: fn(&M) -> M)
where
M: toasty::schema::Model + 'static,
{
for link in &mut self.row_links {
if crate::column::reads_own_fields(link.reads.as_ref()) {
let url = link.url.clone();
link.url = Arc::new(move |row: &M| url(&bare(row)));
link.bare = true;
}
}
}
pub(crate) fn row_link_reads_undeclared(&self) -> bool {
self.row_links.iter().any(|link| link.reads.is_none())
}
}