Parse the JSON into a union type. Let’s call it the AST.
Use the AST to generate the UI.
Modify the AST whenever a change is made to the UI.
On save, convert the AST back to JSON and send to the server.
Questions:
Does my plan make sense or sound reasonable?
How would I go about making updates deep in the AST when a change is made via the UI?
Related to part 2, maybe the AST as a union type is not the best representation since I’d need to make many updates to it as the user messes around with the UI. What then might be a better data structure?
Personally I’d go with a modification of the plan:
Design a union type to model the UI
Modify it whenever a change is made to the UI
Work on parsing the JSON into that union type
On save, serialize it to JSON and send to the server
I think it’ll be easier to discuss that in the context of some preliminary code. What would the type declaration for your ideal data model to represent this UI (ignoring JSON for now) look like?
For the union type, I’m thinking of starting with something along the lines of:
type Expr
= And (List Term)
| Or (List Term)
type Term
= Condition Condition
| Group Expr
type alias Condition =
{ term : String
, guard : Guard
}
type Guard
= In (List Value)
| NotIn (List Value)
| GreaterThanEqualTo Int
| GreaterThan Int
| LessThanEqualTo Int
| LessThan Int
type Value
= VString String
| VInt Int
expr : Expr
expr =
And
[ Condition { term = "sales_transaction.source_location_id", guard = In [ VString "1" ] }
, Condition { term = "sales_transaction.subtotal", guard = GreaterThanEqualTo 100 }
, Group <| Or
[ Condition { term = "sales_transaction.total_qty", guard = GreaterThanEqualTo 5 }
, Group <| And
[ Condition { term = "customer.custom.is_employee", guard = In [ VString "Yes" ] } ]
]
]
P.S. @rtfeldman Thinking about this some more I realized that I still didn’t follow your advice of designing the union type from the UI and not the JSON. So I’d go back to your step 1 and try that and let you know how it goes. Thanks for the help.