tablo-core 0.10.0

The core toolkit types for Tablo, a server-rendered admin toolkit on Topcoat and Toasty.
Documentation
//! The zero-rows cell and its clear and back-to-first-page links.

use tablo_ui::{table_body, table_cell, table_row};
use topcoat::{Result, context::Cx, view::*};

use super::{EMPTY_LINK_CLASS, Frame, live_link};
use crate::{dom, panel::list::TableSignals, t, table::TableState};

impl Frame<'_> {
    /// Render the zero-rows cell spanning the table, with clear and back-to-first-page links when
    /// filtered.
    pub(super) async fn render_empty_cell<'a>(
        &self,
        cx: &'a Cx,
        state: &TableState,
        path: &str,
        with_actions: bool,
        with_bulk: bool,
        signals: &TableSignals,
    ) -> Result<BoxView<'a>> {
        let mut colspan = self.columns.len();
        if with_bulk {
            colspan += 1;
        }
        if with_actions {
            colspan += 1;
        }
        let filtered = state.search.is_some() || !state.filters.is_empty();
        let clear_url = filtered.then(|| {
            if state.search.is_some() {
                state.without_search(path)
            } else {
                state.without_filters(path)
            }
        });
        // `reason` is the hook tests read in place of the message.
        let (reason, message) = match &state.search {
            Some(term) => (
                dom::empty::SEARCH,
                t!(cx, "tablo-list-empty-search", term = term.clone()),
            ),
            None if !state.filters.is_empty() => {
                (dom::empty::FILTERS, t!(cx, "tablo-list-empty-filters"))
            }
            None => (dom::empty::NONE, t!(cx, "tablo-list-empty")),
        };
        let clears_search = state.search.is_some();
        let clear_label = if clears_search {
            t!(cx, "tablo-list-clear-search")
        } else {
            t!(cx, "tablo-list-clear-filters")
        };
        let first_page_url =
            (state.cursor.is_some() || state.page.is_some()).then(|| state.first_page(path));
        let clear_link: Option<BoxView<'a>> = clear_url.map(|url| {
            let attrs = live_link(cx, url, signals);
            view! {
                <a
                    class=(EMPTY_LINK_CLASS)
                    data-empty-link=(dom::empty::CLEAR_LINK)
                    (attrs)
                >
                    (clear_label)
                </a>
            }
            .boxed()
        });
        let first_page_link: Option<BoxView<'a>> = first_page_url.map(|url| {
            let attrs = live_link(cx, url, signals);
            view! {
                <a
                    class=(EMPTY_LINK_CLASS)
                    data-empty-link=(dom::empty::FIRST_PAGE_LINK)
                    (attrs)
                >
                    (t!(cx, "tablo-list-first-page"))
                </a>
            }
            .boxed()
        });
        let action: Option<Child<'a>> =
            (clear_link.is_some() || first_page_link.is_some()).then(|| {
                view! {
                    if let Some(link) = clear_link {
                        (link)
                    }
                    if let Some(link) = first_page_link {
                        (link)
                    }
                }
                .boxed()
                .into()
            });
        Ok(view! {
            table_body(
                table_row(
                    table_cell(
                        attrs: attributes! { colspan=(colspan) class="whitespace-normal!" },
                        tablo_ui::empty_state(
                            title: message,
                            action: action,
                            attrs: attributes! { data-empty=(reason) }
                        )
                    )
                )
            )
        }
        .boxed())
    }
}