diff --git a/app/queries/create_group.graphql b/app/queries/create_group.graphql new file mode 100644 index 0000000..96ea2fa --- /dev/null +++ b/app/queries/create_group.graphql @@ -0,0 +1,6 @@ +mutation CreateGroup($name: String!) { + createGroup(name: $name) { + id + displayName + } +} diff --git a/app/src/components/app.rs b/app/src/components/app.rs index 6a76e06..d3bef83 100644 --- a/app/src/components/app.rs +++ b/app/src/components/app.rs @@ -1,6 +1,7 @@ use crate::{ components::{ change_password::ChangePasswordForm, + create_group::CreateGroupForm, create_user::CreateUserForm, group_details::GroupDetails, group_table::GroupTable, @@ -113,10 +114,13 @@ impl Component for App { {"Create a user"} }, + AppRoute::CreateGroup => html! { + + }, AppRoute::ListGroups => html! {
- //{"Create a user"} + {"Create a group"}
}, AppRoute::GroupDetails(group_id) => html! { diff --git a/app/src/components/create_group.rs b/app/src/components/create_group.rs new file mode 100644 index 0000000..cbcf561 --- /dev/null +++ b/app/src/components/create_group.rs @@ -0,0 +1,153 @@ +use crate::{components::router::AppRoute, infra::api::HostService}; +use anyhow::{bail, Result}; +use graphql_client::GraphQLQuery; +use validator_derive::Validate; +use yew::prelude::*; +use yew::services::{fetch::FetchTask, ConsoleService}; +use yew_form_derive::Model; +use yew_router::{ + agent::{RouteAgentDispatcher, RouteRequest}, + route::Route, +}; + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "../schema.graphql", + query_path = "queries/create_group.graphql", + response_derives = "Debug", + custom_scalars_module = "crate::infra::graphql" +)] +pub struct CreateGroup; + +pub struct CreateGroupForm { + link: ComponentLink, + route_dispatcher: RouteAgentDispatcher, + form: yew_form::Form, + error: Option, + // Used to keep the request alive long enough. + _task: Option, +} + +#[derive(Model, Validate, PartialEq, Clone, Default)] +pub struct CreateGroupModel { + #[validate(length(min = 1, message = "Groupname is required"))] + groupname: String, +} + +pub enum Msg { + Update, + SubmitForm, + CreateGroupResponse(Result), +} + +impl CreateGroupForm { + fn handle_msg(&mut self, msg: ::Message) -> Result { + match msg { + Msg::Update => Ok(true), + Msg::SubmitForm => { + if !self.form.validate() { + bail!("Check the form for errors"); + } + let model = self.form.model(); + let req = create_group::Variables { + name: model.groupname, + }; + self._task = Some(HostService::graphql_query::( + req, + self.link.callback(Msg::CreateGroupResponse), + "Error trying to create group", + )?); + Ok(true) + } + Msg::CreateGroupResponse(r) => { + match r { + Err(e) => return Err(e), + Ok(r) => ConsoleService::log(&format!( + "Created group '{}'", + &r.create_group.display_name + )), + }; + self.route_dispatcher + .send(RouteRequest::ChangeRoute(Route::from(AppRoute::ListGroups))); + Ok(true) + } + } + } +} + +impl Component for CreateGroupForm { + type Message = Msg; + type Properties = (); + + fn create(_: Self::Properties, link: ComponentLink) -> Self { + Self { + link, + route_dispatcher: RouteAgentDispatcher::new(), + form: yew_form::Form::::new(CreateGroupModel::default()), + error: None, + _task: None, + } + } + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + self.error = None; + match self.handle_msg(msg) { + Err(e) => { + ConsoleService::error(&e.to_string()); + self.error = Some(e); + true + } + Ok(b) => b, + } + } + + fn change(&mut self, _: Self::Properties) -> ShouldRender { + false + } + + fn view(&self) -> Html { + type Field = yew_form::Field; + html! { + <> +
+
+ +
+ +
+ {&self.form.field_message("groupname")} +
+
+
+
+ +
+
+ { if let Some(e) = &self.error { + html! { +
+ {e.to_string() } +
+ } + } else { html! {} } + } + + } + } +} diff --git a/app/src/components/create_user.rs b/app/src/components/create_user.rs index dae42df..1dbabaa 100644 --- a/app/src/components/create_user.rs +++ b/app/src/components/create_user.rs @@ -1,4 +1,4 @@ -use crate::infra::api::HostService; +use crate::{components::router::AppRoute, infra::api::HostService}; use anyhow::{bail, Context, Result}; use graphql_client::GraphQLQuery; use lldap_auth::{opaque, registration}; @@ -158,9 +158,7 @@ impl CreateUserForm { } Msg::SuccessfulCreation => { self.route_dispatcher - .send(RouteRequest::ChangeRoute(Route::new_no_state( - "/list_users", - ))); + .send(RouteRequest::ChangeRoute(Route::from(AppRoute::ListUsers))); Ok(true) } } diff --git a/app/src/components/group_details.rs b/app/src/components/group_details.rs index b4c56c8..6adbd1c 100644 --- a/app/src/components/group_details.rs +++ b/app/src/components/group_details.rs @@ -147,6 +147,7 @@ impl GroupDetails { html! { {"No members"} + } } else { diff --git a/app/src/components/mod.rs b/app/src/components/mod.rs index 192efe7..8bcd281 100644 --- a/app/src/components/mod.rs +++ b/app/src/components/mod.rs @@ -2,6 +2,7 @@ pub mod add_group_member; pub mod add_user_to_group; pub mod app; pub mod change_password; +pub mod create_group; pub mod create_user; pub mod delete_group; pub mod delete_user; diff --git a/app/src/components/router.rs b/app/src/components/router.rs index 1c8f107..7831fa5 100644 --- a/app/src/components/router.rs +++ b/app/src/components/router.rs @@ -15,6 +15,8 @@ pub enum AppRoute { ChangePassword(String), #[to = "/user/{user_id}"] UserDetails(String), + #[to = "/groups/create"] + CreateGroup, #[to = "/groups"] ListGroups, #[to = "/group/{group_id}"]