diff --git a/crates/frontend/src/components/condition_pills.rs b/crates/frontend/src/components/condition_pills.rs index 6a083293..1757a69d 100644 --- a/crates/frontend/src/components/condition_pills.rs +++ b/crates/frontend/src/components/condition_pills.rs @@ -5,6 +5,137 @@ use crate::components::condition_pills::types::ConditionOperator; use self::types::Condition; use leptos::*; +use wasm_bindgen::JsCast; +use web_sys::Element; + +#[component] +pub fn condition_expression( + #[prop(into)] id: String, + #[prop(into)] list_id: String, + condition: Condition, +) -> impl IntoView { + let (expand_rs, expand_ws) = create_signal(false); + + let classes = Signal::derive(move || { + if expand_rs.get() { + ( + "pointer flex items-center w-max max-w-full rounded-md bg-gray-50 px-2 py-1 text-xs ring-1 ring-inset ring-purple-700/10 shadow-md gap-x-2 overflow-hidden", + "font-mono font-semibold context_condition w-full text-wrap word-break-break" + ) + } else { + ( + "pointer flex items-center w-max max-w-[300px] rounded-md bg-gray-50 px-2 py-1 text-xs ring-1 ring-inset ring-purple-700/10 shadow-md gap-x-2 overflow-hidden whitespace-nowrap", + + "font-mono font-semibold context_condition w-full text-ellipsis overflow-hidden whitespace-nowrap" + ) + } + }); + + let condition = store_value(condition); + let id = store_value(id); + + let click_event_handler = window_event_listener(ev::click, move |ev| { + if let Some(t) = ev.target() { + let target_element = t.dyn_into::(); + if let Ok(te) = target_element { + let parent_id = te.parent_element().map(|e| e.id()); + + if let Some(p_id) = parent_id { + if !p_id.contains(&list_id) { + expand_ws.set(false); + } + } + } + } + }); + on_cleanup(|| { + click_event_handler.remove(); + }); + + view! { + {move || { + let (list_item_class, value_class) = classes.get(); + let Condition { left_operand: dimension, operator, right_operand: value } = condition + .get_value(); + view! { +
  • + + + {dimension} + + + {operator.to_string()} + + + {match operator { + ConditionOperator::Between => { + let split_val: Vec = value + .clone() + .split(',') + .map(String::from) + .collect(); + view! { + <> + + {&split_val[0]} + + + {"and"} + + + {&split_val[1]} + + + } + } + _ => { + view! { + <> + {value} + + } + } + }} + +
  • + } + }} + } +} + +#[component] +pub fn condition( + #[prop(into)] id: String, + #[prop(into)] conditions: Vec, + #[prop(into, default=String::new())] class: String, +) -> impl IntoView { + let outer_div_class = format!("{} pt-3 relative flex flex-col w-full py-4 pl-6 border-l-2 border-gray-300 rounded-lg", class); + view! { +
    +
      + {conditions + .into_iter() + .enumerate() + .map(|(idx, condition)| { + let item_id = format!("{}-{}", id, idx); + view! { } + }) + .collect::>()} +
    + + "and" + +
    + } +} #[component] pub fn condition_pills(#[prop(into)] conditions: Vec) -> impl IntoView { diff --git a/crates/frontend/src/components/context_card.rs b/crates/frontend/src/components/context_card.rs index 57a32a6f..cd7cb03a 100644 --- a/crates/frontend/src/components/context_card.rs +++ b/crates/frontend/src/components/context_card.rs @@ -3,7 +3,7 @@ use serde_json::{Map, Value}; use crate::{ components::{ - condition_pills::{types::Condition, ConditionPills}, + condition_pills::{types::Condition, Condition as ConditionComponent}, table::{types::Column, Table}, }, types::Context, @@ -13,9 +13,16 @@ use crate::{ pub fn context_card( context: Context, overrides: Map, - handle_edit: Callback<(Context, Map), ()>, - handle_clone: Callback<(Context, Map), ()>, - handle_delete: Callback, + #[prop(default = true)] show_actions: bool, + #[prop(default=Callback::new(|_| {}))] handle_edit: Callback< + (Context, Map), + (), + >, + #[prop(default=Callback::new(|_| {}))] handle_clone: Callback< + (Context, Map), + (), + >, + #[prop(default=Callback::new(|_| {}))] handle_delete: Callback, ) -> impl IntoView { let conditions: Vec = (&context).try_into().unwrap_or(vec![]); let override_table_rows = overrides @@ -28,6 +35,7 @@ pub fn context_card( }) .collect::>>(); + let context_id = StoredValue::new(context.id.clone()); let context = StoredValue::new(context); let overrides = StoredValue::new(overrides); @@ -37,43 +45,49 @@ pub fn context_card( ]; view! { -
    +
    -
    -

    - "Condition" -

    - - -
    -
    - - - - - -
    +

    + "Condition" +

    + +
    + + + + + +
    +
    -
    - + +
    +
    + } diff --git a/crates/frontend/src/hoc/layout.rs b/crates/frontend/src/hoc/layout.rs index 0f2aa5ab..d01963fe 100644 --- a/crates/frontend/src/hoc/layout.rs +++ b/crates/frontend/src/hoc/layout.rs @@ -36,7 +36,7 @@ pub fn Layout(children: Children) -> impl IntoView {
    // params_map=params_map -
    +
    {children()}
    diff --git a/crates/frontend/src/pages/home.rs b/crates/frontend/src/pages/home.rs index f30592a6..a24488f0 100644 --- a/crates/frontend/src/pages/home.rs +++ b/crates/frontend/src/pages/home.rs @@ -1,8 +1,9 @@ use std::time::Duration; use crate::components::condition_pills::types::Condition; -use crate::components::condition_pills::ConditionPills; +use crate::components::condition_pills::Condition as ConditionComponent; use crate::components::skeleton::{Skeleton, SkeletonVariant}; +use crate::types::Config; use crate::{ api::{fetch_config, fetch_dimensions}, components::{ @@ -50,6 +51,115 @@ fn gen_name_id(s0: &String, s1: &String, s2: &String) -> String { format!("{s0}::{s1}::{s2}") } +#[component] +fn all_context_view(config: Config) -> impl IntoView { + let Config { + contexts, + overrides, + default_configs, + } = config; + let rows = |k: &String, v: &Value, striked: bool| { + let default_iter = vec![(k.clone(), v.clone())]; + v + .as_object() + .unwrap_or(&Map::from_iter(default_iter)) + .iter() + .map(|(key, value)| { + let key = key.replace('"', "").trim().to_string(); + let value = value + .as_str() + .unwrap_or(value.to_string().trim_matches('"')) + .into(); + let unique_name = gen_name_id(&key, &key, &value); + view! { +
    + + + + } + }).collect_view() + }; + + view! { +
    + {contexts + .iter() + .map(|context| { + let rows: Vec<_> = context + .override_with_keys + .iter() + .filter_map(|key| overrides.get(key).map(|o| rows(key, o, true))) + .collect(); + let conditions: Vec = context.try_into().unwrap_or_default(); + view! { +
    +

    + "Condition" +

    +
    + +
    +
    + {key} + + + {check_url_and_return_val(value) } + +
    + + + + + + + {rows} +
    KeyValue
    +
    +
    +
    + } + }) + .rev() + .collect::>()}
    +
    +

    Default Configuration

    + + + + + + + + + + {default_configs + .iter() + .map(|(k, v)| rows(k, v, false)) + .collect::>()} + + +
    KeyValue
    +
    +
    + + } +} + #[component] pub fn home() -> impl IntoView { let tenant_rs = use_context::>().unwrap(); @@ -217,7 +327,7 @@ pub fn home() -> impl IntoView { }); }; view! { -
    +
    } @@ -337,104 +447,9 @@ pub fn home() -> impl IntoView { .with(move |result| { match result { Some(Ok(config)) => { - let rows = |k: &String, v: &Value, striked: bool| { - let mut view_vector = vec![]; - let default_iter = vec![(k.clone(), v.clone())]; - for (key, value) in v - .as_object() - .unwrap_or(&Map::from_iter(default_iter)) - .iter() - { - let key = key.replace('"', "").trim().to_string(); - let value = value - .as_str() - .unwrap_or(value.to_string().trim_matches('"')) - .into(); - let unique_name = gen_name_id(&key, &key, &value); - view_vector - .push( - view! { - < tr > < td class = "min-w-48 max-w-72 font-mono" > < span - name = format!("{unique_name}-1") class = "config-name" - class : text - black = { ! striked } class : font - bold = { - ! striked } class : text - gray - 300 = { striked } > { key - } < td class = - "min-w-48 max-w-72 font-mono" style = - "word-break: break-word;" > < span name = - format!("{unique_name}-2") class = "config-value" class : - text - black = { ! striked } class : font - bold = { ! - striked } class : text - gray - 300 = { striked } > { - check_url_and_return_val(value) } - }, - ) - } - view_vector - }; - let contexts_views: Vec<_> = config - .contexts - .iter() - .map(|context| { - let rows: Vec<_> = context - .override_with_keys - .iter() - .filter_map(|key| { - config.overrides.get(key).map(|o| (key, o)) - }) - .map(|(k, v)| { rows(k, v, true) }) - .collect(); - let conditions: Vec = context - .try_into() - .unwrap_or_default(); - view! { -
    -
    -

    - -

    - - - - - - - - {rows} -
    KeyValue
    - -
    -
    - } - }) - .collect::>(); - let new_context_views = contexts_views - .into_iter() - .rev() - .collect::>(); - let default_config: Vec<_> = config - .default_configs - .iter() - .map(|(k, v)| { rows(k, v, false) }) - .collect(); vec![ - view! { -
    - {new_context_views} -
    -
    -

    Default Configuration

    - - - - - - - - {default_config} -
    KeyValue
    -
    -
    -
    - }, + view! { } + .into_view(), ] } Some(Err(error)) => { @@ -443,12 +458,14 @@ pub fn home() -> impl IntoView {
    Failed to fetch config data: {error.to_string()}
    - }, + } + .into_view(), ] } None => { vec![ - view! {
    No config data fetched
    }, + view! {
    No config data fetched
    } + .into_view(), ] } } diff --git a/crates/frontend/styles/tailwind.css b/crates/frontend/styles/tailwind.css index eece7805..617365d2 100644 --- a/crates/frontend/styles/tailwind.css +++ b/crates/frontend/styles/tailwind.css @@ -27,6 +27,7 @@ .context_condition{ font-size: 0.9rem; + text-wrap: nowrap; } .value_link { @@ -86,3 +87,12 @@ .min-w-48 { min-width: 12rem; } + +span.and-badge { + margin: 0; +} + +/* .table-zebra tbody tr:nth-child(2n-1) { + --tw-bg-opacity: 1; + background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity))); +}*/