aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/components/Modal
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/js/components/Modal')
-rw-r--r--web/src/js/components/Modal/OptionMaster.jsx119
-rw-r--r--web/src/js/components/Modal/OptionModal.jsx27
2 files changed, 141 insertions, 5 deletions
diff --git a/web/src/js/components/Modal/OptionMaster.jsx b/web/src/js/components/Modal/OptionMaster.jsx
new file mode 100644
index 00000000..c25dda72
--- /dev/null
+++ b/web/src/js/components/Modal/OptionMaster.jsx
@@ -0,0 +1,119 @@
+import PropTypes from 'prop-types'
+
+PureBooleanOption.PropTypes = {
+ value: PropTypes.bool.isRequired,
+ onChange: PropTypes.func.isRequired,
+}
+
+function PureBooleanOption({ value, onChange, name, help}) {
+ return (
+ <label>
+ { name }
+ <input type="checkbox"
+ checked={value}
+ onChange={onChange}
+ title={help}
+ />
+ </label>
+ )
+}
+
+PureStringOption.PropTypes = {
+ value: PropTypes.string.isRequired,
+ onChange: PropTypes.func.isRequired,
+}
+
+function PureStringOption( { value, onChange, name, help }) {
+ let onKeyDown = (e) => {e.stopPropagation()}
+ return (
+ <label>
+ { name }
+ <input type="text"
+ value={value}
+ onChange={onChange}
+ title={help}
+ onKeyDown={onKeyDown}
+ />
+ </label>
+ )
+}
+
+PureNumberOption.PropTypes = {
+ value: PropTypes.number.isRequired,
+ onChange: PropTypes.func.isRequired,
+}
+
+function PureNumberOption( {value, onChange, name, help }) {
+ let onKeyDown = (e) => {e.stopPropagation()}
+ return (
+ <label>
+ { name }
+ <input type="number"
+ value={value}
+ onChange={onChange}
+ title={help}
+ onKeyDown={onKeyDown}
+ />
+ </label>
+ )
+}
+
+PureChoicesOption.PropTypes = {
+ value: PropTypes.string.isRequired,
+ onChange: PropTypes.func.isRequired,
+}
+
+function PureChoicesOption( { value, onChange, name, help, choices }) {
+ return (
+ <label htmlFor="">
+ { name }
+ <select name={name} onChange={onChange} title={help} selected={value}>
+ { choices.map((choice, index) => (
+ <option key={index} value={choice}> {choice} </option>
+ ))}
+ </select>
+ </label>
+ )
+}
+
+const OptionTypes = {
+ bool: PureBooleanOption,
+ str: PureStringOption,
+ int: PureNumberOption,
+ "optional str": PureStringOption,
+ "sequence of str": PureStringOption,
+}
+
+export default function OptionMaster({option, name, updateOptions, ...props}) {
+ let WrappedComponent = null
+ if (option.choices) {
+ WrappedComponent = PureChoicesOption
+ } else {
+ WrappedComponent = OptionTypes[option.type]
+ }
+
+ let onChange = (e) => {
+ switch (option.type) {
+ case 'bool' :
+ updateOptions({[name]: !option.value})
+ break
+ case 'int':
+ updateOptions({[name]: parseInt(e.target.value)})
+ break
+ default:
+ updateOptions({[name]: e.target.value})
+ }
+ }
+ return (
+ <div className="menu-entry">
+ <WrappedComponent
+ children={props.children}
+ value={option.value}
+ onChange={onChange}
+ name={name}
+ help={option.help}
+ choices={option.choices}
+ />
+ </div>
+ )
+}
diff --git a/web/src/js/components/Modal/OptionModal.jsx b/web/src/js/components/Modal/OptionModal.jsx
index 500495c4..ef3a224a 100644
--- a/web/src/js/components/Modal/OptionModal.jsx
+++ b/web/src/js/components/Modal/OptionModal.jsx
@@ -1,16 +1,18 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'
import * as modalAction from '../../ducks/ui/modal'
+import { update as updateOptions } from '../../ducks/options'
+import Option from './OptionMaster'
class PureOptionModal extends Component {
constructor(props, context) {
super(props, context)
- this.state = { title: 'Options', }
+ this.state = { title: 'Options' }
}
render() {
- const { hideModal } = this.props
+ const { hideModal, options } = this.props
const { title } = this.state
return (
<div>
@@ -26,7 +28,19 @@ class PureOptionModal extends Component {
</div>
<div className="modal-body">
- ...
+ {
+ Object.keys(options).sort()
+ .map((key, index) => {
+ let option = options[key];
+ return (
+ <Option
+ key={index}
+ name={key}
+ updateOptions={updateOptions}
+ option={option}
+ />)
+ })
+ }
</div>
<div className="modal-footer">
@@ -39,7 +53,10 @@ class PureOptionModal extends Component {
export default connect(
state => ({
-
+ options: state.options
}),
- { hideModal: modalAction.hideModal }
+ {
+ hideModal: modalAction.hideModal,
+ updateOptions: updateOptions,
+ }
)(PureOptionModal)