// rocie - An enterprise grocery management system - Web app // // Copyright (C) 2026 Benedikt Peetz // SPDX-License-Identifier: GPL-3.0-or-later // // This file is part of Rocie. // // You should have received a copy of the License along with this program. // If not, see . use leptos::{ IntoView, component, prelude::{ClassAttribute, ElementChild}, view, }; use rocie_client::models::{Product, ProductParent}; use crate::{ api::{ product_parents_toplevel_wrapped, product_parents_under_404_wrapped, products_by_product_parent_id_direct_wrapped, products_by_product_parent_id_indirect_wrapped, products_without_product_parent_wrapped, }, components::{ async_fetch::{AsyncFetch, AsyncResource}, catch_errors::CatchErrors, login_wall::LoginWall, site_header::SiteHeader, }, pages::mk_render_parents, }; #[component] pub fn Products() -> impl IntoView { view! {
    { AsyncFetch! { @map_error_in_producer from_resource = AsyncResource!( () -> Result<(Vec, Vec), leptos::error::Error> { Ok(( product_parents_toplevel_wrapped().await?, products_without_product_parent_wrapped().await? )) } ), producer = |(parents, toplevel_products)| render_product_parents(Some(parents), Some(toplevel_products)), } }
} } mk_render_parents!( self = render_product_parents, parent_type = ProductParent, item_type = Product, value_renderer = render_products, under_parent_fetcher = product_parents_under_404_wrapped, indirect_fetcher = products_by_product_parent_id_indirect_wrapped, direct_fetcher = products_by_product_parent_id_direct_wrapped, ); fn render_products(products: Vec) -> impl IntoView { products .into_iter() .map(|product| { view! {
  • {product.name}
  • } }) .collect::>() }