diff --git a/crates/frontend/src/components/condition_pills.rs b/crates/frontend/src/components/condition_pills.rs index 02d4bc1d..f28da555 100644 --- a/crates/frontend/src/components/condition_pills.rs +++ b/crates/frontend/src/components/condition_pills.rs @@ -1,5 +1,5 @@ use crate::{ - logic::{Condition, Conditions, Operand, Operator}, + logic::{Conditions, Constant, Expression, Operator}, schema::HtmlDisplay, }; @@ -32,10 +32,10 @@ pub fn use_condition_collapser() -> WindowListenerHandle { pub fn condition_expression( #[prop(into)] id: String, #[prop(into)] list_id: String, - condition: Condition, + expression: Expression, ) -> impl IntoView { let id = store_value(id); - let condition = store_value(condition); + let expression = store_value(expression); let (expand_rs, expand_ws) = create_signal(false); let condition_id_rs = use_context::>().expect( @@ -57,16 +57,14 @@ pub fn condition_expression( } else { ("condition-item-collapsed", "condition-value-collapsed") }; - let Condition { dimension, operator, operands } = condition.get_value(); - let operand_str: Vec = operands - .iter() - .filter_map(|operand| { - match operand { - Operand::Dimension(_) => None, - Operand::Value(v) => Some(v.html_display()), - } - }) - .collect(); + let (dimension, operator, operands): (String, Operator, Vec) = expression + .with_value(|exp| { + ( + exp.variable_name(), + exp.to_operator(), + exp.to_constants_vec().iter().map(|c| c.html_display()).collect(), + ) + }); view! {
  • - {match operator { - Operator::Between => { - if operand_str.len() == 2 { - view! { - <> - - {&operand_str[0]} - - - {"and"} - - - {&operand_str[1]} - - - } - .into_view() - } else { - view! { - - "Invalid between values" + {match expression.get_value() { + Expression::Between(Constant(c1), _, Constant(c2)) => { + view! { + <> + + {c1.html_display()} + + + {"and"} + + + {c2.html_display()} - } - .into_view() + } + .into_view() } _ => { - let rendered_value = operand_str.join(", "); + let rendered_value = operands.join(", "); view! { {rendered_value} }.into_view() } }} @@ -146,11 +135,11 @@ pub fn condition( .get_value() .iter() .enumerate() - .map(|(idx, condition)| { + .map(|(idx, expression)| { let item_id = format!("{}-{}", id, idx); view! { diff --git a/crates/frontend/src/components/context_card.rs b/crates/frontend/src/components/context_card.rs index e6104442..16efc45d 100644 --- a/crates/frontend/src/components/context_card.rs +++ b/crates/frontend/src/components/context_card.rs @@ -7,7 +7,7 @@ use crate::{ condition_pills::Condition as ConditionComponent, table::{types::Column, Table}, }, - logic::{Conditions, Operator}, + logic::{Conditions, Expression}, }; #[component] @@ -52,12 +52,12 @@ pub fn context_card( && !conditions .0 .iter() - .any(|condition| condition.dimension == "variantIds"); + .any(|expression| expression.variable_name() == "variantIds"); let edit_unsupported = conditions .0 .iter() - .any(|condition| matches!(condition.operator, Operator::Other(_))); + .any(|expression| matches!(expression, Expression::Other(_, _))); view! {
    diff --git a/crates/frontend/src/components/context_form.rs b/crates/frontend/src/components/context_form.rs index 019cb4d9..f73a0679 100644 --- a/crates/frontend/src/components/context_form.rs +++ b/crates/frontend/src/components/context_form.rs @@ -2,7 +2,7 @@ pub mod utils; use std::collections::{HashMap, HashSet}; use crate::components::input::{Input, InputType}; -use crate::logic::{Condition, Conditions, Operand, Operands, Operator}; +use crate::logic::{Conditions, Constant, Expression, Operator, Variable}; use crate::schema::EnumVariants; use crate::types::Dimension; use crate::{ @@ -17,19 +17,72 @@ pub fn condition_input( disabled: bool, resolve_mode: bool, allow_remove: bool, - condition: StoredValue, + expression: StoredValue, input_type: StoredValue, schema_type: StoredValue, #[prop(into)] on_remove: Callback, - #[prop(into)] on_value_change: Callback<(usize, Value), ()>, + #[prop(into)] on_value_change: Callback, #[prop(into)] on_operator_change: Callback, ) -> impl IntoView { - let Condition { - dimension, - operator, - operands, - } = condition.get_value(); + let (dimension, operator) = + expression.with_value(|v| (v.variable_name(), v.to_operator())); + let inputs: Vec<(Value, Callback)> = match expression.get_value() { + Expression::Is(Variable(v), Constant(c)) => { + vec![( + c, + Callback::new(move |value: Value| { + on_value_change + .call(Expression::Is(Variable(v.clone()), Constant(value))); + }), + )] + } + Expression::In(Variable(v), Constant(c)) => { + vec![( + c, + Callback::new(move |value: Value| { + on_value_change + .call(Expression::In(Variable(v.clone()), Constant(value))); + }), + )] + } + Expression::Has(Constant(c), Variable(v)) => { + vec![( + c, + Callback::new(move |value: Value| { + on_value_change + .call(Expression::Has(Constant(value), Variable(v.clone()))); + }), + )] + } + Expression::Between(Constant(c1), Variable(v), Constant(c2)) => { + let v_clone = v.clone(); + let c2_clone = c2.clone(); + vec![ + ( + c1.clone(), + Callback::new(move |value: Value| { + on_value_change.call(Expression::Between( + Constant(value), + Variable(v_clone.clone()), + Constant(c2_clone.clone()), + )); + }), + ), + ( + c2.clone(), + Callback::new(move |value: Value| { + on_value_change.call(Expression::Between( + Constant(c1.clone()), + Variable(v.clone()), + Constant(value), + )); + }), + ), + ] + } + _ => vec![], + }; view! {
    @@ -87,48 +140,39 @@ pub fn condition_input(
    - {operands - .0 - .clone() + {inputs .into_iter() .enumerate() - .map(|(idx, operand): (usize, Operand)| { - match operand { - Operand::Dimension(_) => view! {}.into_view(), - Operand::Value(v) => { - view! { - ))| { + view! { + - } - .into_view() - } + class="w-[450px]" + name="" + operator=Some(operator.clone()) + /> } }) - .collect_view()} - + .collect_view()}