use crate::{ components::{ delete_user::DeleteUser, router::{AppRoute, Link}, }, infra::common_component::{CommonComponent, CommonComponentParts}, }; use anyhow::{Error, Result}; use graphql_client::GraphQLQuery; use yew::prelude::*; #[derive(GraphQLQuery)] #[graphql( schema_path = "../schema.graphql", query_path = "queries/list_users.graphql", response_derives = "Debug", custom_scalars_module = "crate::infra::graphql" )] pub struct ListUsersQuery; use list_users_query::{RequestFilter, ResponseData}; type User = list_users_query::ListUsersQueryUsers; pub struct UserTable { common: CommonComponentParts, users: Option>, } pub enum Msg { ListUsersResponse(Result), OnUserDeleted(String), OnError(Error), } impl CommonComponent for UserTable { fn handle_msg(&mut self, msg: ::Message) -> Result { match msg { Msg::ListUsersResponse(users) => { self.users = Some(users?.users.into_iter().collect()); Ok(true) } Msg::OnError(e) => Err(e), Msg::OnUserDeleted(user_id) => { debug_assert!(self.users.is_some()); self.users.as_mut().unwrap().retain(|u| u.id != user_id); Ok(true) } } } fn mut_common(&mut self) -> &mut CommonComponentParts { &mut self.common } } impl UserTable { fn get_users(&mut self, req: Option) { self.common.call_graphql::( list_users_query::Variables { filters: req }, Msg::ListUsersResponse, "Error trying to fetch users", ); } } impl Component for UserTable { type Message = Msg; type Properties = (); fn create(props: Self::Properties, link: ComponentLink) -> Self { let mut table = UserTable { common: CommonComponentParts::::create(props, link), users: None, }; table.get_users(None); table } fn update(&mut self, msg: Self::Message) -> ShouldRender { CommonComponentParts::::update(self, msg) } fn change(&mut self, _: Self::Properties) -> ShouldRender { false } fn view(&self) -> Html { html! {
{self.view_users()} {self.view_errors()}
} } } impl UserTable { fn view_users(&self) -> Html { let make_table = |users: &Vec| { html! {
{users.iter().map(|u| self.view_user(u)).collect::>()}
{"User ID"} {"Email"} {"Display name"} {"First name"} {"Last name"} {"Creation date"} {"Delete"}
} }; match &self.users { None => html! {{"Loading..."}}, Some(users) => make_table(users), } } fn view_user(&self, user: &User) -> Html { html! { {&user.id} {&user.email} {&user.display_name} {&user.first_name} {&user.last_name} {&user.creation_date.date().naive_local()} } } fn view_errors(&self) -> Html { match &self.common.error { None => html! {}, Some(e) => html! {
{"Error: "}{e.to_string()}
}, } } }