From aa01a62df7ce015ba4bf3c5ba9f3074616530496 Mon Sep 17 00:00:00 2001
From: Matthew Shao <me@matshao.com>
Date: Wed, 5 Jul 2017 08:40:21 +0800
Subject: [web] Add keys argument for dump_dict in optmanager.

---
 web/src/js/components/Modal/OptionMaster.jsx | 138 +++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 web/src/js/components/Modal/OptionMaster.jsx

(limited to 'web/src/js/components/Modal/OptionMaster.jsx')

diff --git a/web/src/js/components/Modal/OptionMaster.jsx b/web/src/js/components/Modal/OptionMaster.jsx
new file mode 100644
index 00000000..e16319fb
--- /dev/null
+++ b/web/src/js/components/Modal/OptionMaster.jsx
@@ -0,0 +1,138 @@
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
+import { update as updateOptions } from '../../ducks/options'
+
+PureBooleanOption.PropTypes = {
+    value: PropTypes.bool.isRequired,
+    onChange: PropTypes.func.isRequired,
+}
+
+function PureBooleanOption({ value, onChange, name, help}) {
+        return (
+            <div className="menu-entry">
+                <label>
+                    <input type="checkbox"
+                            checked={value}
+                            onChange={onChange}
+                            title={help}
+                    />
+                    { name }
+                </label>
+            </div>
+        )
+}
+
+PureStringOption.PropTypes = {
+    value: PropTypes.string.isRequired,
+    onChange: PropTypes.func.isRequired,
+}
+
+function PureStringOption( { value, onChange, name, help }) {
+    let onKeyDown = (e) => {e.stopPropagation()}
+    return (
+        <div className="menu-entry">
+            <label>
+                { name }
+                <input type="text"
+                        value={value}
+                        onChange={onChange}
+                        title={help}
+                        onKeyDown={onKeyDown}
+                />
+            </label>
+        </div>
+    )
+}
+
+PureNumberOption.PropTypes = {
+    value: PropTypes.number.isRequired,
+    onChange: PropTypes.func.isRequired,
+}
+
+function PureNumberOption( {value, onChange, name, help }) {
+    let onKeyDown = (e) => {e.stopPropagation()}
+    return (
+        <div className="menu-entry">
+            <label>
+                { name }
+                <input type="number"
+                        value={value}
+                        onChange={onChange}
+                        title={help}
+                        onKeyDown={onKeyDown}
+                />
+            </label>
+        </div>
+    )
+}
+
+PureChoicesOption.PropTypes = {
+    value: PropTypes.string.isRequired,
+    onChange: PropTypes.func.isRequired,
+}
+
+function PureChoicesOption( { value, onChange, name, help, choices }) {
+    return (
+        <div className="menu-entry">
+            <label htmlFor="">
+                { name }
+                <select name={name} onChange={onChange} title={help} selected={value}>
+                    { choices.map(choice => (
+                        <option value={choice}> {choice} </option>
+                    ))}
+                </select>
+            </label>
+        </div>
+    )
+}
+
+const OptionTypes = {
+    bool: PureBooleanOption,
+    str: PureStringOption,
+    int: PureNumberOption,
+    "optional str": PureStringOption,
+    "sequence of str": PureStringOption,
+}
+
+Wrapper.displayName = 'OptionWrapper'
+
+
+function Wrapper({option, options, updateOptions, ...props}) {
+    let optionObj = options[option],
+        WrappedComponent = null
+    if (optionObj.choices) {
+        WrappedComponent = PureChoicesOption
+    } else {
+        WrappedComponent = OptionTypes[optionObj.type]
+    }
+
+    let onChange = (e) => {
+        switch (optionObj.type) {
+            case 'bool' :
+                updateOptions({[option]: !optionObj.value})
+                break
+            case 'int':
+                updateOptions({[option]: parseInt(e.target.value)})
+                break
+            default:
+                updateOptions({[option]: e.target.value})
+        }
+    }
+    return <WrappedComponent
+        children={props.children}
+        value={optionObj.value}
+        onChange={onChange}
+        name={option}
+        help={optionObj.help}
+        choices={optionObj.choices}
+    />
+}
+
+export default connect(
+    state => ({
+        options: state.options,
+    }),
+    {
+        updateOptions,
+    }
+)(Wrapper)
-- 
cgit v1.2.3

