Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: JSONSchema generated forms for contexts #257

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

ShubhranshuSanjeev
Copy link
Collaborator

@ShubhranshuSanjeev ShubhranshuSanjeev commented Sep 30, 2024

Problem

Context forms were generated using lot of broken, clumsy pattern matching logic, parsing of values and generating final context json's logic was spread across utility functions.

Solution

Replaced pattern matching over string to guess the type of value with algebraic representation of JsonLogic.
Single Input component, which works seemlessly with the schema type of the dimensions and render appropriate fields along with handling parsing and input validation.

@ShubhranshuSanjeev ShubhranshuSanjeev force-pushed the fix/context-form branch 2 times, most recently from 25de1f1 to d86f41d Compare October 8, 2024 08:11
impl Operand {
pub fn from_operand_json(value: Value) -> Self {
match value {
Value::Object(ref o) if o.contains_key("var") => Operand::Dimension(value),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ref required here ?
Can we remove it ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want a reference.

@ShubhranshuSanjeev ShubhranshuSanjeev force-pushed the fix/context-form branch 2 times, most recently from 0cca50a to 5346aa1 Compare October 23, 2024 10:22
@ShubhranshuSanjeev ShubhranshuSanjeev changed the title Fix/context form fix: JSONSchema generated forms for contexts Oct 23, 2024
@ShubhranshuSanjeev ShubhranshuSanjeev marked this pull request as ready for review October 28, 2024 08:25
@ShubhranshuSanjeev ShubhranshuSanjeev requested a review from a team as a code owner October 28, 2024 08:25
@ShubhranshuSanjeev ShubhranshuSanjeev force-pushed the fix/context-form branch 3 times, most recently from 533787b to f6a3529 Compare November 18, 2024 09:47
Operands(
iter.into_iter()
.map(Operand::from_operand_json)
.collect::<Vec<Operand>>(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make a type for Vec as Operands as we made for Conditions ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't really understand the point.

let on_context_edit = Callback::new(move |data: (Context, Map<String, Value>)| {
let (context, overrides) = data;
let conditions =
Conditions::from_context_json(&context.condition.into()).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid using plain unwrap here ?

let on_context_clone = Callback::new(move |data: (Context, Map<String, Value>)| {
let (context, overrides) = data;
let conditions =
Conditions::from_context_json(&context.condition.into()).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


open_drawer("context_and_override_drawer");
});
open_drawer("context_and_override_drawer");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create ENUMs for these strings , it's a little dangerous to keep it as strings

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drawers are going away in my next PR, so this will be redundant work.

@ShubhranshuSanjeev ShubhranshuSanjeev changed the base branch from main to feat/json-logic-repr December 4, 2024 07:46
@ShubhranshuSanjeev ShubhranshuSanjeev force-pushed the fix/context-form branch 2 times, most recently from 15e6abd to c5fddd0 Compare December 4, 2024 07:50
@ShubhranshuSanjeev ShubhranshuSanjeev force-pushed the feat/json-logic-repr branch 2 times, most recently from 9886f4d to 96705d5 Compare December 4, 2024 11:39
@ShubhranshuSanjeev ShubhranshuSanjeev force-pushed the fix/context-form branch 2 times, most recently from 5db64f5 to 23db368 Compare December 4, 2024 11:57
@Datron Datron requested a review from sauraww December 9, 2024 07:29
@ShubhranshuSanjeev ShubhranshuSanjeev changed the base branch from feat/json-logic-repr to main December 10, 2024 11:21
@@ -106,18 +86,18 @@ pub fn condition_expression(
</span>

{match operator {
ConditionOperator::Between => {
if filtered_vals.len() == 2 {
Operator::Between => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this, it begs the question, should we instead parse at the expression level?
You know something like: Expr::Between(o1, o2). That way, you could tie the operands & operator together.
Did you by any chance already give this a thought?

) -> Result<Value, String> {
match op {
Operator::In => match type_ {
JsonSchemaType::String => serde_json::from_str::<Vec<String>>(s)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a bit repetitive, can we refactor this a little?

) -> Result<Self, Self::Error> {
match operator {
Operator::Is => Ok(Operands(vec![
Operand::Dimension(json!({ "var": d_name })),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, a little odd that dimension is also an operand. 🤔

set_form_mode.set(Some(FormMode::Edit));
open_drawer("context_and_override_drawer");
}
Err(e) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point in the program, if this call errs out, there's no useful error we can report to the user to un-block them. So maybe, it makes sense to use some kind of front-end panic which let's us write code as if there was no chance of an error to begin with. What do you think?


#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Expression {
Is(Variable, Constant),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, don't know if the variable should be part of the Expression, or the Condition 🤔. Somehow I feel like Condition wrapping a variable and an Expression(w/ just the consants) makes more sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants