From b5db94c5b7736ce3732bb961ab9f3b522ff6909d Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 8 Feb 2020 23:22:21 +0000 Subject: [PATCH] Starting to add simple autogenerated forms --- src/EAFunds/EAFunds_Form.bs.js | 40 ++++++++++++++++++++- src/EAFunds/EAFunds_Form.re | 25 ++++++++++++- src/Model.re | 66 ++++++++++++++++++++++++++++++++-- 3 files changed, 127 insertions(+), 4 deletions(-) diff --git a/src/EAFunds/EAFunds_Form.bs.js b/src/EAFunds/EAFunds_Form.bs.js index 390f1675..4800201f 100644 --- a/src/EAFunds/EAFunds_Form.bs.js +++ b/src/EAFunds/EAFunds_Form.bs.js @@ -1,8 +1,46 @@ 'use strict'; +var $$Array = require("bs-platform/lib/js/array.js"); +var Curry = require("bs-platform/lib/js/curry.js"); +var React = require("react"); +var Belt_Option = require("bs-platform/lib/js/belt_Option.js"); +var Belt_MapString = require("bs-platform/lib/js/belt_MapString.js"); +var Model$ProbExample = require("../Model.bs.js"); var EAFunds_Model$ProbExample = require("./EAFunds_Model.bs.js"); +function handleChange(handleChange$1, $$event) { + return Curry._1(handleChange$1, $$event.target.value); +} + var model = EAFunds_Model$ProbExample.Interface.model; +var initialMap = Model$ProbExample.toMaps(model); + +function EAFunds_Form(Props) { + var match = React.useState((function () { + return Model$ProbExample.toMaps(model); + })); + var params = match[0]; + return $$Array.map((function (parameter) { + var __x = Belt_MapString.get(params[/* inputs */1], parameter[/* id */0]); + var value = Belt_Option.flatMap(__x, (function (param) { + return param[1]; + })); + return React.createElement(React.Fragment, undefined, parameter[/* name */1], parameter[/* id */0], React.createElement(Model$ProbExample.Input.Form.make, { + parameter: parameter, + value: value, + onChange: (function (r) { + console.log(r); + return /* () */0; + }) + })); + }), $$Array.of_list(model[/* inputs */3])); +} + +var make = EAFunds_Form; + +exports.handleChange = handleChange; exports.model = model; -/* EAFunds_Model-ProbExample Not a pure module */ +exports.initialMap = initialMap; +exports.make = make; +/* initialMap Not a pure module */ diff --git a/src/EAFunds/EAFunds_Form.re b/src/EAFunds/EAFunds_Form.re index 24e2a994..383b5477 100644 --- a/src/EAFunds/EAFunds_Form.re +++ b/src/EAFunds/EAFunds_Form.re @@ -1 +1,24 @@ -let model = EAFunds_Model.Interface.model; \ No newline at end of file +let model = EAFunds_Model.Interface.model; + +let handleChange = (handleChange, event) => + handleChange(ReactEvent.Form.target(event)##value); + +let model = EAFunds_Model.Interface.model; +let initialMap = Model.toMaps(model); + +[@react.component] +let make = () => { + let (params, changeParams) = React.useState(() => Model.toMaps(model)); + model.inputs + |> Array.of_list + |> Array.map((parameter: Model.Input.parameter) => { + let value = + params.inputs->Model.MS.get(parameter.id) + |> Belt.Option.flatMap(_, ((_, b)) => b); + <> + {parameter.name |> ReasonReact.string} + {parameter.id |> ReasonReact.string} + Js.log(r)} /> + ; + }); +}; \ No newline at end of file diff --git a/src/Model.re b/src/Model.re index 498b213e..be60f874 100644 --- a/src/Model.re +++ b/src/Model.re @@ -37,8 +37,15 @@ module Input = { type parameterType = | Year(IOTypes.withDefaultMinMax(float)) | SingleChoice(IOTypes.singleChoice) - | FloatPoint - | FloatCdf; + | FloatPoint; + + let toInput = (p: parameterType) => + switch (p) { + | Year(r) => r.default->Belt.Option.map(p => InputTypes.Year(p)) + | SingleChoice(r) => + r.default->Belt.Option.map(p => InputTypes.SingleChoice(p)) + | FloatPoint => None + }; type parameter = { id: string, @@ -57,6 +64,33 @@ module Input = { name, parameterType, }; + + module Form = { + let handleChange = (handleChange, event) => + handleChange(ReactEvent.Form.target(event)##value); + [@react.component] + let make = + (~parameter: parameter, ~value: option(InputTypes.t), ~onChange) => { + switch (parameter.parameterType, value) { + | (Year(_), Some(Year(r))) => + Js.Float.toString} + onChange={handleChange(r => + switch (Js.Float.fromString(r)) { + | r => onChange(_ => Some(InputTypes.Year(r))) + } + )} + /> + | (FloatPoint, Some(FloatPoint(r))) => + Js.Float.toString} /> + | (Year(_), _) + | (FloatPoint, _) => + | (SingleChoice(_), _) => +
{"Single Choice" |> ReasonReact.string}
+ }; + }; + }; }; module Output = { @@ -101,6 +135,34 @@ let gatherInputs = (m: model, a: list(InputTypes.withName)) => { |> List.flatten; }; +module MS = Belt.Map.String; + +type modelMaps = { + assumptions: MS.t((Input.parameter, option(InputTypes.t))), + inputs: MS.t((Input.parameter, option(InputTypes.t))), + output: (Output.parameter, option(InputTypes.t)), +}; + +let toMaps = (m: model): modelMaps => { + assumptions: + MS.fromArray( + m.assumptions + |> List.map((r: Input.parameter) => + (r.id, (r, Input.toInput(r.parameterType))) + ) + |> Array.of_list, + ), + inputs: + MS.fromArray( + m.inputs + |> List.map((r: Input.parameter) => + (r.id, (r, Input.toInput(r.parameterType))) + ) + |> Array.of_list, + ), + output: (Output.make(~name="Payouts", ~parameterType=FloatCdf, ()), None), +}; + type modelParams = { assumptions: list(option(InputTypes.t)), inputs: list(option(InputTypes.t)),