use crate::{ components::{ form::{checkbox::CheckBox, field::Field, select::Select, submit::Submit}, router::AppRoute, }, convert_attribute_type, infra::{ common_component::{CommonComponent, CommonComponentParts}, schema::{validate_attribute_type, AttributeType}, }, }; use anyhow::{bail, Result}; use gloo_console::log; use graphql_client::GraphQLQuery; use validator_derive::Validate; use yew::prelude::*; use yew_form_derive::Model; use yew_router::{prelude::History, scope_ext::RouterScopeExt}; #[derive(GraphQLQuery)] #[graphql( schema_path = "../schema.graphql", query_path = "queries/create_user_attribute.graphql", response_derives = "Debug", custom_scalars_module = "crate::infra::graphql" )] pub struct CreateUserAttribute; convert_attribute_type!(create_user_attribute::AttributeType); pub struct CreateUserAttributeForm { common: CommonComponentParts, form: yew_form::Form, } #[derive(Model, Validate, PartialEq, Eq, Clone, Default, Debug)] pub struct CreateUserAttributeModel { #[validate(length(min = 1, message = "attribute_name is required"))] attribute_name: String, #[validate(custom = "validate_attribute_type")] attribute_type: String, is_editable: bool, is_list: bool, is_visible: bool, } pub enum Msg { Update, SubmitForm, CreateUserAttributeResponse(Result), } impl CommonComponent for CreateUserAttributeForm { fn handle_msg( &mut self, ctx: &Context, 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(); if model.is_editable && !model.is_visible { bail!("Editable attributes must also be visible"); } let attribute_type = model.attribute_type.parse::().unwrap(); let req = create_user_attribute::Variables { name: model.attribute_name, attribute_type: create_user_attribute::AttributeType::from(attribute_type), is_editable: model.is_editable, is_list: model.is_list, is_visible: model.is_visible, }; self.common.call_graphql::( ctx, req, Msg::CreateUserAttributeResponse, "Error trying to create user attribute", ); Ok(true) } Msg::CreateUserAttributeResponse(response) => { response?; let model = self.form.model(); log!(&format!( "Created user attribute '{}'", model.attribute_name )); ctx.link().history().unwrap().push(AppRoute::ListUserSchema); Ok(true) } } } fn mut_common(&mut self) -> &mut CommonComponentParts { &mut self.common } } impl Component for CreateUserAttributeForm { type Message = Msg; type Properties = (); fn create(_: &Context) -> Self { let model = CreateUserAttributeModel { attribute_type: AttributeType::String.to_string(), ..Default::default() }; Self { common: CommonComponentParts::::create(), form: yew_form::Form::::new(model), } } fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { CommonComponentParts::::update(self, ctx, msg) } fn view(&self, ctx: &Context) -> Html { let link = ctx.link(); html! {
{"Create a user attribute"}
label="Name" required={true} form={&self.form} field_name="attribute_name" oninput={link.callback(|_| Msg::Update)} /> label="Type" required={true} form={&self.form} field_name="attribute_type" oninput={link.callback(|_| Msg::Update)}> > label="Multiple values" form={&self.form} field_name="is_list" ontoggle={link.callback(|_| Msg::Update)} /> label="Visible to users" form={&self.form} field_name="is_visible" ontoggle={link.callback(|_| Msg::Update)} /> label="Editable by users" form={&self.form} field_name="is_editable" ontoggle={link.callback(|_| Msg::Update)} /> { if let Some(e) = &self.common.error { html! {
{e.to_string() }
} } else { html! {} } }
} } }