From 582c595edd27cf0d100e3c29dd9c1531130b8773 Mon Sep 17 00:00:00 2001 From: Austin Alvarado Date: Sat, 20 Jan 2024 18:27:47 +0000 Subject: [PATCH] putting a pin in it --- app/queries/get_group_details.graphql | 16 ++++ app/src/components/group_attributes_form.rs | 83 +++++++++++++++++++++ app/src/components/group_details.rs | 30 +++++++- app/src/components/mod.rs | 1 + 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 app/src/components/group_attributes_form.rs diff --git a/app/queries/get_group_details.graphql b/app/queries/get_group_details.graphql index 00400d7..703eb68 100644 --- a/app/queries/get_group_details.graphql +++ b/app/queries/get_group_details.graphql @@ -8,5 +8,21 @@ query GetGroupDetails($id: Int!) { id displayName } + attributes { + name + value + } + } + schema { + groupSchema { + attributes { + name + attributeType + isList + isVisible + isEditable + isHardcoded + } + } } } diff --git a/app/src/components/group_attributes_form.rs b/app/src/components/group_attributes_form.rs new file mode 100644 index 0000000..3f32100 --- /dev/null +++ b/app/src/components/group_attributes_form.rs @@ -0,0 +1,83 @@ +use std::ops::Deref; + +use crate::{ + components::{ + group_details::Attribute, + router::{AppRoute, Link}, + }, + infra::common_component::{CommonComponent, CommonComponentParts}, +}; +use anyhow::{bail, Error, Result}; +use gloo_console::log; +use graphql_client::GraphQLQuery; +use yew::prelude::*; + +#[derive(Properties, PartialEq)] +pub struct AttributeInputProps { + pub attribute: Attribute, + pub on_changed: Callback<(String, Vec)>, +} + +#[function_component(SingleAttributeInput)] +fn single_attribute_input(props: &AttributeInputProps) -> Html { + let attribute = props.attribute.clone(); + let on_changed = props.on_changed.clone(); + let on_input = Callback::from(move |e: InputEvent| on_changed.emit((attribute.name.clone(), vec![e.data().unwrap_or_default()]))); + html!{ +
+ +
+ +
+
+ } +} + +#[function_component(ListAttributeInput)] +fn list_attribute_input(props: &AttributeInputProps) -> Html { + html!{} +} + +#[function_component(AttributeInput)] +fn attribute_input(props: &AttributeInputProps) -> Html { + if props.attribute.is_list { + html!{ + + } + } else { + html!{ + + } + } +} + +#[derive(Properties, PartialEq)] +pub struct Props { + pub attributes: Vec, +} + +#[function_component(GroupAttributesForm)] +pub fn group_attributes_form(Props{ attributes }: &Props) -> Html { + let attributes = use_state(|| attributes.clone()); + let on_changed = { + let attributes = attributes.clone(); + Callback::from(move |(name, value): (String, Vec)| { + let mut new_attributes = attributes.deref().clone(); + new_attributes.iter_mut().filter(|attribute| attribute.name == name).for_each(|attribute| attribute.value = value.clone()); + attributes.set(new_attributes.clone()); + log!("New attributes:"); + new_attributes.iter().for_each(|attribute| log!("Name: {attribute.name}, Value: {attribute.value}")); + }) + }; + html!{ + {for attributes.iter().map(|attribute| html!{})} + } +} \ No newline at end of file diff --git a/app/src/components/group_details.rs b/app/src/components/group_details.rs index ae32436..115c59e 100644 --- a/app/src/components/group_details.rs +++ b/app/src/components/group_details.rs @@ -2,6 +2,7 @@ use crate::{ components::{ add_group_member::{self, AddGroupMemberComponent}, remove_user_from_group::RemoveUserFromGroupComponent, + group_attributes_form::GroupAttributesForm, router::{AppRoute, Link}, }, infra::common_component::{CommonComponent, CommonComponentParts}, @@ -22,12 +23,22 @@ pub struct GetGroupDetails; pub type Group = get_group_details::GetGroupDetailsGroup; pub type User = get_group_details::GetGroupDetailsGroupUsers; pub type AddGroupMemberUser = add_group_member::User; +pub type AttributeSchema = get_group_details::GetGroupDetailsSchemaGroupSchemaAttributes; + +#[derive(Clone, PartialEq, Eq)] +pub struct Attribute { + pub name: String, + pub value: Vec, + pub attribute_type: String, + pub is_list: bool, +} pub struct GroupDetails { common: CommonComponentParts, /// The group info. If none, the error is in `error`. If `error` is None, then we haven't /// received the server response yet. group: Option, + attributes: Vec, } /// State machine describing the possible transitions of the component state. @@ -185,7 +196,22 @@ impl CommonComponent for GroupDetails { fn handle_msg(&mut self, _: &Context, msg: ::Message) -> Result { match msg { Msg::GroupDetailsResponse(response) => match response { - Ok(group) => self.group = Some(group.group), + Ok(response) => { + let group = response.group; + self.group = Some(group.clone()); + let set_attributes = group.attributes.clone(); + let mut attribute_schema = response.schema.group_schema.attributes; + attribute_schema.retain(|schema| !schema.is_hardcoded); + let attributes = attribute_schema.into_iter().map(|schema| { + Attribute { + name: schema.name.clone(), + value: set_attributes.iter().find(|attribute_value| attribute_value.name == schema.name).unwrap().value.clone(), + attribute_type: format!("{:?}",schema.attribute_type), + is_list: schema.is_list, + } + }).collect(); + self.attributes = attributes; + }, Err(e) => { self.group = None; bail!("Error getting user details: {}", e); @@ -222,6 +248,7 @@ impl Component for GroupDetails { let mut table = Self { common: CommonComponentParts::::create(), group: None, + attributes: Vec::default(), }; table.get_group_details(ctx); table @@ -239,6 +266,7 @@ impl Component for GroupDetails { html! {
{self.view_details(u)} + {self.view_user_list(ctx, u)} {self.view_add_user_button(ctx, u)} {self.view_messages(error)} diff --git a/app/src/components/mod.rs b/app/src/components/mod.rs index f78dcf9..89c0259 100644 --- a/app/src/components/mod.rs +++ b/app/src/components/mod.rs @@ -6,6 +6,7 @@ pub mod create_group; pub mod create_user; pub mod delete_group; pub mod delete_user; +pub mod group_attributes_form; pub mod group_details; pub mod group_table; pub mod login;