Simple form working end-to-end
This commit is contained in:
parent
edaa7a7ca5
commit
54e645f252
|
@ -1,46 +1 @@
|
|||
'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;
|
||||
exports.initialMap = initialMap;
|
||||
exports.make = make;
|
||||
/* initialMap Not a pure module */
|
||||
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
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}
|
||||
<Model.Input.Form parameter value onChange={r => Js.log(r)} />
|
||||
</>;
|
||||
});
|
||||
};
|
||||
// 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}
|
||||
// <Model.Input.Form parameter value onChange={r => Js.log(r)} />
|
||||
// </>;
|
||||
// });
|
||||
/* }*/
|
|
@ -1,52 +1,50 @@
|
|||
open EAFunds_Data;
|
||||
|
||||
let handleChange = (handleChange, event) =>
|
||||
handleChange(ReactEvent.Form.target(event)##value);
|
||||
|
||||
[@react.component]
|
||||
let make = () => {
|
||||
let (year, setYear) = React.useState(() => 2021.);
|
||||
<>
|
||||
<h1> {"EA Funds Forecasting Model 0.1" |> ReasonReact.string} </h1>
|
||||
<input
|
||||
type_="number"
|
||||
value={year |> Js.Float.toString}
|
||||
onChange={handleChange(r =>
|
||||
switch (Js.Float.fromString(r)) {
|
||||
| r when r >= 2020.0 && r <= 2050.0 => setYear(_ => r)
|
||||
| _ => ()
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<table className="table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2"> {"Fund Name" |> ReasonReact.string} </th>
|
||||
<th className="px-4 py-2"> {"Donations" |> ReasonReact.string} </th>
|
||||
<th className="px-4 py-2"> {"Payouts" |> ReasonReact.string} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{funds
|
||||
|> Belt.Array.map(_, r =>
|
||||
<tr>
|
||||
<th className="px-4 py-2 border ">
|
||||
{r.name |> ReasonReact.string}
|
||||
</th>
|
||||
<th className="px-4 py-2 border font-normal">
|
||||
{EAFunds_Model.go(r.group, year, DONATIONS)
|
||||
|> Model.InputTypes.to_string
|
||||
|> ReasonReact.string}
|
||||
</th>
|
||||
<th className="px-4 py-2 border font-normal">
|
||||
{EAFunds_Model.go(r.group, year, PAYOUTS)
|
||||
|> Model.InputTypes.to_string
|
||||
|> ReasonReact.string}
|
||||
</th>
|
||||
</tr>
|
||||
)
|
||||
|> ReasonReact.array}
|
||||
</tbody>
|
||||
</table>
|
||||
</>;
|
||||
};
|
||||
// open EAFunds_Data;
|
||||
// let handleChange = (handleChange, event) =>
|
||||
// handleChange(ReactEvent.Form.target(event)##value);
|
||||
// [@react.component]
|
||||
// let make = () => {
|
||||
// let (year, setYear) = React.useState(() => 2021.);
|
||||
// <>
|
||||
// <h1> {"EA Funds Forecasting Model 0.1" |> ReasonReact.string} </h1>
|
||||
// <input
|
||||
// type_="number"
|
||||
// value={year |> Js.Float.toString}
|
||||
// onChange={handleChange(r =>
|
||||
// switch (Js.Float.fromString(r)) {
|
||||
// | r when r >= 2020.0 && r <= 2050.0 => setYear(_ => r)
|
||||
// | _ => ()
|
||||
// }
|
||||
// )}
|
||||
// />
|
||||
// <table className="table-auto">
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th className="px-4 py-2"> {"Fund Name" |> ReasonReact.string} </th>
|
||||
// <th className="px-4 py-2"> {"Donations" |> ReasonReact.string} </th>
|
||||
// <th className="px-4 py-2"> {"Payouts" |> ReasonReact.string} </th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// {funds
|
||||
// |> Belt.Array.map(_, r =>
|
||||
// <tr>
|
||||
// <th className="px-4 py-2 border ">
|
||||
// {r.name |> ReasonReact.string}
|
||||
// </th>
|
||||
// <th className="px-4 py-2 border font-normal">
|
||||
// {EAFunds_Model.go(r.group, year, DONATIONS)
|
||||
// |> Model.InputTypes.to_string
|
||||
// |> ReasonReact.string}
|
||||
// </th>
|
||||
// <th className="px-4 py-2 border font-normal">
|
||||
// {EAFunds_Model.go(r.group, year, PAYOUTS)
|
||||
// |> Model.InputTypes.to_string
|
||||
// |> ReasonReact.string}
|
||||
// </th>
|
||||
// </tr>
|
||||
// )
|
||||
// |> ReasonReact.array}
|
||||
// </tbody>
|
||||
// </table>
|
||||
// </>;
|
||||
/* }*/
|
|
@ -1,8 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
var Block = require("bs-platform/lib/js/block.js");
|
||||
var Curry = require("bs-platform/lib/js/curry.js");
|
||||
var React = require("react");
|
||||
var Math$ProbExample = require("../Math.bs.js");
|
||||
var Model$ProbExample = require("../Model.bs.js");
|
||||
var Prop$ProbExample = require("../Prop.bs.js");
|
||||
|
||||
function yearDiff(year) {
|
||||
return year - 2020.0;
|
||||
|
@ -66,46 +68,38 @@ var PayoutsIfAround = {
|
|||
};
|
||||
|
||||
function go(group, year, output) {
|
||||
return /* FloatCdf */Block.__(3, [calculateDifference(currentValue(group, output), year, /* record */[
|
||||
return /* FloatCdf */Block.__(2, [calculateDifference(currentValue(group, output), year, /* record */[
|
||||
/* meanDiff */1.1,
|
||||
/* stdDiff */1.1
|
||||
])]);
|
||||
}
|
||||
|
||||
var model_002 = /* assumptions : :: */[
|
||||
Model$ProbExample.Input.make("Yearly Growth Rate", /* FloatPoint */0, undefined, /* () */0),
|
||||
/* :: */[
|
||||
Model$ProbExample.Input.currentYear,
|
||||
/* [] */0
|
||||
]
|
||||
];
|
||||
|
||||
var model_003 = /* inputs : :: */[
|
||||
Model$ProbExample.Input.make("Fund", /* SingleChoice */Block.__(1, [/* record */[
|
||||
var model_002 = /* inputTypes : array */[
|
||||
Prop$ProbExample.TypeWithMetadata.make("Fund", /* SelectSingle */Block.__(0, [/* record */[
|
||||
/* options : :: */[
|
||||
/* tuple */[
|
||||
"Animal Welfare Fund",
|
||||
"animal"
|
||||
/* record */[
|
||||
/* id */"animal",
|
||||
/* name */"Animal Welfare Fund"
|
||||
],
|
||||
/* :: */[
|
||||
/* tuple */[
|
||||
"Global Health Fund",
|
||||
"globalHealth"
|
||||
/* record */[
|
||||
/* id */"globalHealth",
|
||||
/* name */"Global Health Fund"
|
||||
],
|
||||
/* :: */[
|
||||
/* tuple */[
|
||||
"Long Term Future Fund",
|
||||
"longTerm"
|
||||
/* record */[
|
||||
/* id */"longTerm",
|
||||
/* name */"Long Term Future Fund"
|
||||
],
|
||||
/* :: */[
|
||||
/* tuple */[
|
||||
"Meta Fund",
|
||||
"meta"
|
||||
/* record */[
|
||||
/* id */"longterm",
|
||||
/* name */"Meta Fund"
|
||||
],
|
||||
/* :: */[
|
||||
/* tuple */[
|
||||
"All",
|
||||
"all"
|
||||
/* record */[
|
||||
/* id */"all",
|
||||
/* name */"All"
|
||||
],
|
||||
/* [] */0
|
||||
]
|
||||
|
@ -114,32 +108,21 @@ var model_003 = /* inputs : :: */[
|
|||
]
|
||||
],
|
||||
/* default */"total"
|
||||
]]), undefined, /* () */0),
|
||||
/* :: */[
|
||||
Model$ProbExample.Input.make("Year", /* Year */Block.__(0, [/* record */[
|
||||
]]), undefined, undefined, undefined, /* () */0),
|
||||
Prop$ProbExample.TypeWithMetadata.make("Year", /* Year */Block.__(2, [/* record */[
|
||||
/* default */2030.0,
|
||||
/* min */2020.0,
|
||||
/* max */2050.0
|
||||
]]), undefined, /* () */0),
|
||||
/* [] */0
|
||||
]
|
||||
]]), undefined, undefined, undefined, /* () */0)
|
||||
];
|
||||
|
||||
var model_004 = /* outputs : :: */[
|
||||
Model$ProbExample.Output.make("Payments", /* FloatCdf */2, undefined, /* () */0),
|
||||
/* :: */[
|
||||
Model$ProbExample.Output.make("Payouts", /* FloatCdf */2, undefined, /* () */0),
|
||||
/* [] */0
|
||||
]
|
||||
];
|
||||
var model_003 = /* outputTypes : array */[];
|
||||
|
||||
var model = /* record */[
|
||||
/* name */"Calculate the payments and payouts of EA Funds based on existing data.",
|
||||
/* author */"George Harrison",
|
||||
model_002,
|
||||
model_003,
|
||||
model_004,
|
||||
/* outputConfig : Single */0
|
||||
model_003
|
||||
];
|
||||
|
||||
function convertChoice(s) {
|
||||
|
@ -158,48 +141,54 @@ function convertChoice(s) {
|
|||
}
|
||||
|
||||
function run(p) {
|
||||
var match = p[/* assumptions */0];
|
||||
var match$1 = p[/* inputs */1];
|
||||
if (match) {
|
||||
var match$2 = match[0];
|
||||
if (match$2 !== undefined) {
|
||||
var match$3 = match$2;
|
||||
if (match$3.tag) {
|
||||
return ;
|
||||
} else {
|
||||
var match$4 = match[1];
|
||||
if (match$4) {
|
||||
var match$5 = match$4[0];
|
||||
if (match$5 !== undefined && !(match$5.tag || match$4[1] || !match$1)) {
|
||||
var match$6 = match$1[0];
|
||||
if (match$6 !== undefined) {
|
||||
var match$7 = match$6;
|
||||
if (match$7.tag === /* SingleChoice */1 && !match$1[1]) {
|
||||
return go(convertChoice(match$7[0]), match$3[0], /* DONATIONS */0);
|
||||
} else {
|
||||
var partial_arg = p[/* inputValues */1];
|
||||
var partial_arg$1 = Prop$ProbExample.ValueMap.get;
|
||||
var get = function (param) {
|
||||
return partial_arg$1(partial_arg, param);
|
||||
};
|
||||
var match = Curry._1(get, "Fund");
|
||||
var match$1 = Curry._1(get, "Year");
|
||||
if (match !== undefined) {
|
||||
var match$2 = match;
|
||||
switch (match$2.tag | 0) {
|
||||
case /* SelectSingle */0 :
|
||||
if (match$1 !== undefined) {
|
||||
var match$3 = match$1;
|
||||
switch (match$3.tag | 0) {
|
||||
case /* FloatPoint */1 :
|
||||
return go(convertChoice(match$2[0]), match$3[0], /* DONATIONS */0);
|
||||
case /* SelectSingle */0 :
|
||||
case /* FloatCdf */2 :
|
||||
return ;
|
||||
|
||||
}
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
case /* FloatPoint */1 :
|
||||
case /* FloatCdf */2 :
|
||||
return ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function EAFunds_Model$Interface$Form(Props) {
|
||||
return React.createElement(Prop$ProbExample.ModelForm.make, {
|
||||
combo: Prop$ProbExample.Combo.fromModel(model)
|
||||
});
|
||||
}
|
||||
|
||||
var Form = {
|
||||
make: EAFunds_Model$Interface$Form
|
||||
};
|
||||
|
||||
var Interface = {
|
||||
model: model,
|
||||
convertChoice: convertChoice,
|
||||
run: run
|
||||
run: run,
|
||||
Form: Form
|
||||
};
|
||||
|
||||
exports.PayoutsIfAround = PayoutsIfAround;
|
||||
|
|
|
@ -44,7 +44,7 @@ module PayoutsIfAround = {
|
|||
|
||||
let go = (group: group, year: float, output: output) => {
|
||||
PayoutsIfAround.(
|
||||
Model.InputTypes.FloatCdf(
|
||||
Prop.Value.FloatCdf(
|
||||
calculateDifference(
|
||||
currentValue(group, output),
|
||||
year,
|
||||
|
@ -55,34 +55,30 @@ let go = (group: group, year: float, output: output) => {
|
|||
};
|
||||
|
||||
module Interface = {
|
||||
open Model;
|
||||
open Prop;
|
||||
|
||||
let model = {
|
||||
let model: Model.t = {
|
||||
name: "Calculate the payments and payouts of EA Funds based on existing data.",
|
||||
author: "George Harrison",
|
||||
assumptions: [
|
||||
Input.make(~name="Yearly Growth Rate", ~parameterType=FloatPoint, ()),
|
||||
Input.currentYear,
|
||||
],
|
||||
inputs: [
|
||||
Input.make(
|
||||
inputTypes: [|
|
||||
TypeWithMetadata.make(
|
||||
~name="Fund",
|
||||
~parameterType=
|
||||
SingleChoice({
|
||||
~type_=
|
||||
SelectSingle({
|
||||
default: Some("total"),
|
||||
options: [
|
||||
("Animal Welfare Fund", "animal"),
|
||||
("Global Health Fund", "globalHealth"),
|
||||
("Long Term Future Fund", "longTerm"),
|
||||
("Meta Fund", "meta"),
|
||||
("All", "all"),
|
||||
{name: "Animal Welfare Fund", id: "animal"},
|
||||
{name: "Global Health Fund", id: "globalHealth"},
|
||||
{name: "Long Term Future Fund", id: "longTerm"},
|
||||
{name: "Meta Fund", id: "longterm"},
|
||||
{name: "All", id: "all"},
|
||||
],
|
||||
}),
|
||||
(),
|
||||
),
|
||||
Input.make(
|
||||
TypeWithMetadata.make(
|
||||
~name="Year",
|
||||
~parameterType=
|
||||
~type_=
|
||||
Year({
|
||||
default: Some(2030.0),
|
||||
min: Some(2020.0),
|
||||
|
@ -90,12 +86,8 @@ module Interface = {
|
|||
}),
|
||||
(),
|
||||
),
|
||||
],
|
||||
outputs: [
|
||||
Output.make(~name="Payments", ~parameterType=FloatCdf, ()),
|
||||
Output.make(~name="Payouts", ~parameterType=FloatCdf, ()),
|
||||
],
|
||||
outputConfig: Single,
|
||||
|],
|
||||
outputTypes: [||],
|
||||
};
|
||||
|
||||
let convertChoice = (s: string) =>
|
||||
|
@ -107,14 +99,17 @@ module Interface = {
|
|||
| _ => All
|
||||
};
|
||||
|
||||
let run = (p: Model.modelParams) => {
|
||||
switch (p.assumptions, p.inputs) {
|
||||
| (
|
||||
[Some(Year(intendedYear)), Some(Year(currentYear))],
|
||||
[Some(SingleChoice(fund))],
|
||||
) =>
|
||||
let run = (p: Combo.t) => {
|
||||
let get = Prop.ValueMap.get(p.inputValues);
|
||||
switch (get("Fund"), get("Year")) {
|
||||
| (Some(SelectSingle(fund)), Some(FloatPoint(intendedYear))) =>
|
||||
Some(go(convertChoice(fund), intendedYear, DONATIONS))
|
||||
| _ => None
|
||||
};
|
||||
};
|
||||
|
||||
module Form = {
|
||||
[@react.component]
|
||||
let make = () => <Prop.ModelForm combo={Prop.Combo.fromModel(model)} />;
|
||||
};
|
||||
};
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
var React = require("react");
|
||||
var ReactDOMRe = require("reason-react/src/ReactDOMRe.js");
|
||||
var EAFunds_Form2$ProbExample = require("./EAFunds/EAFunds_Form2.bs.js");
|
||||
var EAFunds_Model$ProbExample = require("./EAFunds/EAFunds_Model.bs.js");
|
||||
|
||||
((import('./styles/index.css')));
|
||||
|
||||
ReactDOMRe.renderToElementWithId(React.createElement(EAFunds_Form2$ProbExample.make, { }), "app");
|
||||
ReactDOMRe.renderToElementWithId(React.createElement(EAFunds_Model$ProbExample.Interface.Form.make, { }), "app");
|
||||
|
||||
/* Not a pure module */
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[%bs.raw {|import('./styles/index.css')|}];
|
||||
ReactDOMRe.renderToElementWithId(<EAFunds_Form2 />, "app");
|
||||
ReactDOMRe.renderToElementWithId(<EAFunds_Model.Interface.Form />, "app");
|
|
@ -1,17 +0,0 @@
|
|||
type yearAsFloat = {
|
||||
min: option(float),
|
||||
max: option(float),
|
||||
};
|
||||
|
||||
type namedValue('a) = {
|
||||
name: string,
|
||||
value: 'a,
|
||||
};
|
||||
|
||||
type choice('a) = list(namedValue('a));
|
||||
|
||||
type output =
|
||||
| A
|
||||
| B;
|
||||
|
||||
let nOutput: choice(output) = [{name: "sdfsdf", value: A}];
|
92
src/Prop.re
92
src/Prop.re
|
@ -51,12 +51,12 @@ module Type = {
|
|||
module ValueMap = {
|
||||
module MS = Belt.Map.String;
|
||||
type t = MS.t(Value.t);
|
||||
let get = MS.get;
|
||||
let get = (t: t, s) => MS.get(t, s);
|
||||
let keys = MS.keysToArray;
|
||||
let map = MS.map;
|
||||
let fromArray = (r): t => MS.fromArray(r);
|
||||
let values = (t: t) => t |> MS.valuesToArray;
|
||||
let update = MS.update;
|
||||
let update = (t, k, v) => MS.update(t, k, _ => v);
|
||||
let toArray = MS.toArray;
|
||||
let fromOptionalMap = (t: MS.t(option(Value.t))): t =>
|
||||
MS.keep(t, (_, d) => E.O.isSome(d))
|
||||
|
@ -121,7 +121,7 @@ module Model = {
|
|||
};
|
||||
|
||||
module Combo = {
|
||||
type combo = {
|
||||
type t = {
|
||||
model: Model.t,
|
||||
inputValues: ValueMap.t,
|
||||
outputValues: ValueMap.t,
|
||||
|
@ -135,20 +135,90 @@ module Combo = {
|
|||
)
|
||||
|> ValueMap.fromOptionalArray;
|
||||
|
||||
let isValid = (t: combo) =>
|
||||
let isValid = t =>
|
||||
t.model
|
||||
|> Model.InputTypes.keys
|
||||
|> E.A.fmap(ValueMap.get(t.inputValues))
|
||||
|> Belt.Array.some(_, E.O.isNone);
|
||||
|
||||
let update =
|
||||
(
|
||||
t: combo,
|
||||
key: string,
|
||||
onUpdate: option(Value.t) => option(Value.t),
|
||||
) =>
|
||||
let update = (t, key: string, onUpdate: option(Value.t)) =>
|
||||
ValueMap.update(t.inputValues, key, onUpdate);
|
||||
};
|
||||
|
||||
let run = (t: combo, f): ValueMap.t => f(t.inputValues);
|
||||
let updateInputValue = (t, k, u) => {
|
||||
...t,
|
||||
inputValues: InputValues.update(t, k, u),
|
||||
};
|
||||
|
||||
let inputTypeValuePairs = (t: t) =>
|
||||
t.model.inputTypes
|
||||
|> E.A.fmap((i: TypeWithMetadata.t) =>
|
||||
(i, ValueMap.get(t.inputValues, i.id))
|
||||
);
|
||||
|
||||
let fromModel = (t: Model.t) => {
|
||||
model: t,
|
||||
inputValues: InputValues.defaults(t),
|
||||
outputValues: InputValues.defaults(t),
|
||||
};
|
||||
|
||||
let run = (t: t, f): ValueMap.t => f(t.inputValues);
|
||||
};
|
||||
|
||||
module ValueForm = {
|
||||
let handleChange = (handleChange, event) =>
|
||||
handleChange(ReactEvent.Form.target(event)##value);
|
||||
type onChange = option(Value.t) => unit;
|
||||
|
||||
[@react.component]
|
||||
let make =
|
||||
(
|
||||
~type_: TypeWithMetadata.t,
|
||||
~value: option(Value.t),
|
||||
~onChange: onChange,
|
||||
) => {
|
||||
switch (type_.type_, value) {
|
||||
| (Year(_), Some(FloatPoint(r))) =>
|
||||
<input
|
||||
type_="number"
|
||||
value={r |> Js.Float.toString}
|
||||
onChange={handleChange(r =>
|
||||
switch (Js.Float.fromString(r)) {
|
||||
| r => onChange(Some(Value.FloatPoint(r)))
|
||||
}
|
||||
)}
|
||||
/>
|
||||
| (FloatPoint(_), Some(FloatPoint(r))) =>
|
||||
<input type_="number" value={r |> Js.Float.toString} />
|
||||
| (Year(_), _)
|
||||
| (FloatPoint(_), _) => <input type_="number" value="" />
|
||||
| (SelectSingle(_), _) =>
|
||||
<div> {"Single Choice" |> ReasonReact.string} </div>
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
module ModelForm = {
|
||||
let handleChange = (handleChange, event) =>
|
||||
handleChange(ReactEvent.Form.target(event)##value);
|
||||
|
||||
[@react.component]
|
||||
let make = (~combo: Combo.t) => {
|
||||
let (combo, setCombo) = React.useState(() => combo);
|
||||
<div>
|
||||
{Combo.inputTypeValuePairs(combo)
|
||||
|> E.A.fmap(((type_, value)) =>
|
||||
<ValueForm
|
||||
type_
|
||||
value
|
||||
onChange={newValue =>
|
||||
setCombo(_ =>
|
||||
Combo.updateInputValue(combo, type_.id, newValue)
|
||||
)
|
||||
}
|
||||
/>
|
||||
)
|
||||
|> ReasonReact.array}
|
||||
</div>;
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user