diff --git a/app/src/api.rs b/app/src/api.rs index 3e95476..91d0543 100644 --- a/app/src/api.rs +++ b/app/src/api.rs @@ -97,4 +97,22 @@ impl HostService { }); FetchService::fetch_with_options(request, get_default_options(), handler) } + + pub fn create_user( + request: CreateUserRequest, + callback: Callback>, + ) -> Result { + let url = "/api/users/create"; + let request = Request::post(url) + .header("Content-Type", "application/json") + .body(Json(&request))?; + let handler = create_handler(callback, |status, data: String| { + if status.is_success() { + Ok(()) + } else { + Err(anyhow!("Could not create a user: [{}]: {}", status, data)) + } + }); + FetchService::fetch_with_options(request, get_default_options(), handler) + } } diff --git a/app/src/app.rs b/app/src/app.rs index dae4839..c3f633c 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -1,11 +1,12 @@ -use crate::cookies::get_cookie; -use crate::login::LoginForm; -use crate::logout::LogoutButton; -use crate::user_table::UserTable; +use crate::{ + cookies::get_cookie, create_user::CreateUserForm, login::LoginForm, logout::LogoutButton, + user_table::UserTable, +}; use yew::prelude::*; use yew::services::ConsoleService; use yew_router::{ agent::{RouteAgentDispatcher, RouteRequest}, + components::RouterAnchor, route::Route, router::Router, service::RouteService, @@ -30,10 +31,14 @@ pub enum AppRoute { Login, #[to = "/users"] ListUsers, + #[to = "/create_user"] + CreateUser, #[to = "/"] Index, } +type Link = RouterAnchor; + impl Component for App { type Message = Msg; type Properties = (); @@ -91,10 +96,17 @@ impl Component for App { AppRoute::Login => html! { }, + AppRoute::CreateUser => html! { +
+ + +
+ }, AppRoute::Index | AppRoute::ListUsers => html! {
+ {"Create a user"}
} } diff --git a/app/src/create_user.rs b/app/src/create_user.rs new file mode 100644 index 0000000..32ead31 --- /dev/null +++ b/app/src/create_user.rs @@ -0,0 +1,128 @@ +use crate::api::HostService; +use anyhow::Result; +use lldap_model::*; +use yew::prelude::*; +use yew::services::{fetch::FetchTask, ConsoleService}; +use yew_router::{ + agent::{RouteAgentDispatcher, RouteRequest}, + route::Route, +}; + +pub struct CreateUserForm { + link: ComponentLink, + route_dispatcher: RouteAgentDispatcher, + node_ref: NodeRef, + error: Option, + // Used to keep the request alive long enough. + _task: Option, +} + +pub enum Msg { + CreateUserResponse(Result<()>), + SubmitForm, +} + +impl CreateUserForm { + fn create_user(&mut self, req: CreateUserRequest) { + match HostService::create_user(req, self.link.callback(Msg::CreateUserResponse)) { + Ok(task) => self._task = Some(task), + Err(e) => { + self._task = None; + ConsoleService::log(format!("Error trying to create user: {}", e).as_str()) + } + }; + } +} + +impl Component for CreateUserForm { + type Message = Msg; + type Properties = (); + + fn create(_: Self::Properties, link: ComponentLink) -> Self { + Self { + link, + route_dispatcher: RouteAgentDispatcher::new(), + node_ref: NodeRef::default(), + error: None, + _task: None, + } + } + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::SubmitForm => { + use wasm_bindgen::JsCast; + let document = web_sys::window().unwrap().document().unwrap(); + let get_element = |name: &str| { + document + .get_element_by_id(name) + .unwrap() + .dyn_into::() + .unwrap() + .value() + }; + let req = CreateUserRequest { + user_id: get_element("username"), + email: get_element("email"), + display_name: Some(get_element("displayname")), + first_name: Some(get_element("firstname")), + last_name: Some(get_element("lastname")), + password: get_element("password"), + }; + self.create_user(req); + } + Msg::CreateUserResponse(Ok(())) => { + self.route_dispatcher + .send(RouteRequest::ChangeRoute(Route::new_no_state( + "/list_users", + ))); + } + Msg::CreateUserResponse(Err(e)) => { + ConsoleService::warn(&format!("Error listing users: {}", e)); + } + } + true + } + + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + + fn view(&self) -> Html { + html! { +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ { if let Some(e) = &self.error { + html! { e.to_string() } + } else { html! {} } + } +
+
+ } + } +} diff --git a/app/src/lib.rs b/app/src/lib.rs index a3d8d5f..12fe7d0 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -2,6 +2,7 @@ mod api; mod app; mod cookies; +mod create_user; mod login; mod logout; mod user_table;