diff options
Diffstat (limited to 'src/settings')
| -rw-r--r-- | src/settings/actions/index.ts | 39 | ||||
| -rw-r--r-- | src/settings/actions/setting.ts | 18 | ||||
| -rw-r--r-- | src/settings/components/form/BlacklistForm.tsx | 28 | ||||
| -rw-r--r-- | src/settings/components/form/KeymapsForm.tsx | 32 | ||||
| -rw-r--r-- | src/settings/components/form/PropertiesForm.tsx | 32 | ||||
| -rw-r--r-- | src/settings/components/form/SearchForm.tsx | 38 | ||||
| -rw-r--r-- | src/settings/components/index.tsx | 44 | ||||
| -rw-r--r-- | src/settings/components/ui/AddButton.tsx | 5 | ||||
| -rw-r--r-- | src/settings/components/ui/DeleteButton.tsx | 5 | ||||
| -rw-r--r-- | src/settings/components/ui/Input.tsx | 52 | ||||
| -rw-r--r-- | src/settings/reducers/setting.ts | 16 | 
11 files changed, 193 insertions, 116 deletions
| diff --git a/src/settings/actions/index.ts b/src/settings/actions/index.ts index 016f2a5..75c6bb5 100644 --- a/src/settings/actions/index.ts +++ b/src/settings/actions/index.ts @@ -1,7 +1,32 @@ -export default { -  // Settings -  SETTING_SET_SETTINGS: 'setting.set.settings', -  SETTING_SHOW_ERROR: 'setting.show.error', -  SETTING_SWITCH_TO_FORM: 'setting.switch.to.form', -  SETTING_SWITCH_TO_JSON: 'setting.switch.to.json', -}; +// Settings +export const SETTING_SET_SETTINGS = 'setting.set.settings'; +export const SETTING_SHOW_ERROR = 'setting.show.error'; +export const SETTING_SWITCH_TO_FORM = 'setting.switch.to.form'; +export const SETTING_SWITCH_TO_JSON = 'setting.switch.to.json'; + +interface SettingSetSettingsAcion { +  type: typeof SETTING_SET_SETTINGS; +  source: string; +  json: string; +  form: any; +} + +interface SettingShowErrorAction { +  type: typeof SETTING_SHOW_ERROR; +  error: string; +  json: string; +} + +interface SettingSwitchToFormAction { +  type: typeof SETTING_SWITCH_TO_FORM; +  form: any; +} + +interface SettingSwitchToJsonAction { +  type: typeof SETTING_SWITCH_TO_JSON; +  json: string; +} + +export type SettingAction = +  SettingSetSettingsAcion | SettingShowErrorAction | +  SettingSwitchToFormAction | SettingSwitchToJsonAction; diff --git a/src/settings/actions/setting.ts b/src/settings/actions/setting.ts index db63a45..b03cd80 100644 --- a/src/settings/actions/setting.ts +++ b/src/settings/actions/setting.ts @@ -1,15 +1,15 @@ -import actions from 'settings/actions'; -import * as validator from 'shared/settings/validator'; -import * as settingsValues from 'shared/settings/values'; -import * as settingsStorage from 'shared/settings/storage'; +import * as actions from './index'; +import * as validator from '../../shared/settings/validator'; +import * as settingsValues from '../../shared/settings/values'; +import * as settingsStorage from '../../shared/settings/storage';  import keymaps from '../keymaps'; -const load = async() => { +const load = async(): Promise<actions.SettingAction> => {    let settings = await settingsStorage.loadRaw();    return set(settings);  }; -const save = async(settings) => { +const save = async(settings: any): Promise<actions.SettingAction> => {    try {      if (settings.source === 'json') {        let value = JSON.parse(settings.json); @@ -26,7 +26,7 @@ const save = async(settings) => {    return set(settings);  }; -const switchToForm = (json) => { +const switchToForm = (json: string): actions.SettingAction => {    try {      validator.validate(JSON.parse(json));      let form = settingsValues.formFromJson(json, keymaps.allowedOps); @@ -43,7 +43,7 @@ const switchToForm = (json) => {    }  }; -const switchToJson = (form) => { +const switchToJson = (form: any): actions.SettingAction => {    let json = settingsValues.jsonFromForm(form);    return {      type: actions.SETTING_SWITCH_TO_JSON, @@ -51,7 +51,7 @@ const switchToJson = (form) => {    };  }; -const set = (settings) => { +const set = (settings: any): actions.SettingAction => {    return {      type: actions.SETTING_SET_SETTINGS,      source: settings.source, diff --git a/src/settings/components/form/BlacklistForm.tsx b/src/settings/components/form/BlacklistForm.tsx index c470758..637bc1e 100644 --- a/src/settings/components/form/BlacklistForm.tsx +++ b/src/settings/components/form/BlacklistForm.tsx @@ -2,9 +2,19 @@ import './BlacklistForm.scss';  import AddButton from '../ui/AddButton';  import DeleteButton from '../ui/DeleteButton';  import React from 'react'; -import PropTypes from 'prop-types'; -class BlacklistForm extends React.Component { +interface Props { +  value: string[]; +  onChange: (value: string[]) => void; +  onBlur: () => void; +} + +class BlacklistForm extends React.Component<Props> { +  public static defaultProps: Props = { +    value: [], +    onChange: () => {}, +    onBlur: () => {}, +  };    render() {      return <div className='form-blacklist-form'> @@ -28,7 +38,7 @@ class BlacklistForm extends React.Component {      </div>;    } -  bindValue(e) { +  bindValue(e: any) {      let name = e.target.name;      let index = e.target.getAttribute('data-index');      let next = this.props.value ? this.props.value.slice() : []; @@ -48,16 +58,4 @@ class BlacklistForm extends React.Component {    }  } -BlacklistForm.propTypes = { -  value: PropTypes.arrayOf(PropTypes.string), -  onChange: PropTypes.func, -  onBlur: PropTypes.func, -}; - -BlacklistForm.defaultProps = { -  value: [], -  onChange: () => {}, -  onBlur: () => {}, -}; -  export default BlacklistForm; diff --git a/src/settings/components/form/KeymapsForm.tsx b/src/settings/components/form/KeymapsForm.tsx index 01acf61..ab44464 100644 --- a/src/settings/components/form/KeymapsForm.tsx +++ b/src/settings/components/form/KeymapsForm.tsx @@ -1,10 +1,22 @@  import './KeymapsForm.scss';  import React from 'react'; -import PropTypes from 'prop-types';  import Input from '../ui/Input';  import keymaps from '../../keymaps'; -class KeymapsForm extends React.Component { +type Value = {[key: string]: string}; + +interface Props{ +  value: Value; +  onChange: (e: Value) => void; +  onBlur: () => void; +} + +class KeymapsForm extends React.Component<Props> { +  public static defaultProps: Props = { +    value: {}, +    onChange: () => {}, +    onBlur: () => {}, +  }    render() {      return <div className='form-keymaps-form'> @@ -19,7 +31,7 @@ class KeymapsForm extends React.Component {                  return <Input                    type='text' id={name} name={name} key={name}                    label={label} value={value} -                  onChange={this.bindValue.bind(this)} +                  onValueChange={this.bindValue.bind(this)}                    onBlur={this.props.onBlur}                  />;                }) @@ -30,22 +42,12 @@ class KeymapsForm extends React.Component {      </div>;    } -  bindValue(e) { +  bindValue(name: string, value: string) {      let next = { ...this.props.value }; -    next[e.target.name] = e.target.value; +    next[name] = value;      this.props.onChange(next);    }  } -KeymapsForm.propTypes = { -  value: PropTypes.objectOf(PropTypes.string), -  onChange: PropTypes.func, -}; - -KeymapsForm.defaultProps = { -  value: {}, -  onChange: () => {}, -}; -  export default KeymapsForm; diff --git a/src/settings/components/form/PropertiesForm.tsx b/src/settings/components/form/PropertiesForm.tsx index 979fdd8..0be5f5c 100644 --- a/src/settings/components/form/PropertiesForm.tsx +++ b/src/settings/components/form/PropertiesForm.tsx @@ -1,8 +1,20 @@  import './PropertiesForm.scss';  import React from 'react'; -import PropTypes from 'prop-types'; -class PropertiesForm extends React.Component { +interface Props { +  types: {[key: string]: string}; +  value: {[key: string]: any}; +  onChange: (value: any) => void; +  onBlur: () => void; +} + +class PropertiesForm extends React.Component<Props> { +  public static defaultProps: Props = { +    types: {}, +    value: {}, +    onChange: () => {}, +    onBlur: () => {}, +  };    render() {      let types = this.props.types; @@ -12,13 +24,15 @@ class PropertiesForm extends React.Component {        {          Object.keys(types).map((name) => {            let type = types[name]; -          let inputType = null; +          let inputType = '';            if (type === 'string') {              inputType = 'text';            } else if (type === 'number') {              inputType = 'number';            } else if (type === 'boolean') {              inputType = 'checkbox'; +          } else { +            return null;            }            return <div key={name} className='form-properties-form-row'>              <label> @@ -37,7 +51,7 @@ class PropertiesForm extends React.Component {      </div>;    } -  bindValue(e) { +  bindValue(e: React.ChangeEvent<HTMLInputElement>) {      let name = e.target.name;      let next = { ...this.props.value };      if (e.target.type.toLowerCase() === 'checkbox') { @@ -52,14 +66,4 @@ class PropertiesForm extends React.Component {    }  } -PropertiesForm.propTypes = { -  value: PropTypes.objectOf(PropTypes.any), -  onChange: PropTypes.func, -}; - -PropertiesForm.defaultProps = { -  value: {}, -  onChange: () => {}, -}; -  export default PropertiesForm; diff --git a/src/settings/components/form/SearchForm.tsx b/src/settings/components/form/SearchForm.tsx index 6b0bd01..737e291 100644 --- a/src/settings/components/form/SearchForm.tsx +++ b/src/settings/components/form/SearchForm.tsx @@ -1,10 +1,25 @@  import './SearchForm.scss';  import React from 'react'; -import PropTypes from 'prop-types';  import AddButton from '../ui/AddButton';  import DeleteButton from '../ui/DeleteButton'; -class SearchForm extends React.Component { +interface Value { +  default: string; +  engines: string[][]; +} + +interface Props { +  value: Value; +  onChange: (value: Value) => void; +  onBlur: () => void; +} + +class SearchForm extends React.Component<Props> { +  public static defaultProps: Props = { +    value: { default: '', engines: []}, +    onChange: () => {}, +    onBlur: () => {}, +  }    render() {      let value = this.props.value; @@ -47,11 +62,11 @@ class SearchForm extends React.Component {      </div>;    } -  bindValue(e) { +  bindValue(e: any) {      let value = this.props.value;      let name = e.target.name; -    let index = e.target.getAttribute('data-index'); -    let next = { +    let index = Number(e.target.getAttribute('data-index')); +    let next: Value = {        default: value.default,        engines: value.engines ? value.engines.slice() : [],      }; @@ -76,17 +91,4 @@ class SearchForm extends React.Component {    }  } -SearchForm.propTypes = { -  value: PropTypes.shape({ -    default: PropTypes.string, -    engines: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)), -  }), -  onChange: PropTypes.func, -}; - -SearchForm.defaultProps = { -  value: { default: '', engines: []}, -  onChange: () => {}, -}; -  export default SearchForm; diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx index 4ef59d7..f56e93f 100644 --- a/src/settings/components/index.tsx +++ b/src/settings/components/index.tsx @@ -6,19 +6,29 @@ import SearchForm from './form/SearchForm';  import KeymapsForm from './form/KeymapsForm';  import BlacklistForm from './form/BlacklistForm';  import PropertiesForm from './form/PropertiesForm'; -import * as properties from 'shared/settings/properties'; -import * as settingActions from 'settings/actions/setting'; +import * as properties from '../../shared/settings/properties'; +import * as settingActions from '../../settings/actions/setting';  const DO_YOU_WANT_TO_CONTINUE =    'Some settings in JSON can be lost when migrating.  ' +    'Do you want to continue?'; -class SettingsComponent extends React.Component { +interface Props { +  source: string; +  json: string; +  form: any; +  error: string; + +  // FIXME +  store: any; +} + +class SettingsComponent extends React.Component<Props> {    componentDidMount() {      this.props.dispatch(settingActions.load());    } -  renderFormFields(form) { +  renderFormFields(form: any) {      return <div>        <fieldset>          <legend>Keybindings</legend> @@ -56,15 +66,15 @@ class SettingsComponent extends React.Component {      </div>;    } -  renderJsonFields(json, error) { +  renderJsonFields(json: string, error: string) {      return <div>        <Input          type='textarea'          name='json'          label='Plain JSON' -        spellCheck='false' +        spellCheck={false}          error={error} -        onChange={this.bindJson.bind(this)} +        onValueChange={this.bindJson.bind(this)}          onBlur={this.save.bind(this)}          value={json}        /> @@ -90,7 +100,7 @@ class SettingsComponent extends React.Component {              label='Use form'              checked={this.props.source === 'form'}              value='form' -            onChange={this.bindSource.bind(this)} +            onValueChange={this.bindSource.bind(this)}              disabled={disabled} />            <Input @@ -99,7 +109,7 @@ class SettingsComponent extends React.Component {              label='Use plain JSON'              checked={this.props.source === 'json'}              value='json' -            onChange={this.bindSource.bind(this)} +            onValueChange={this.bindSource.bind(this)}              disabled={disabled} />            { fields }          </form> @@ -107,7 +117,7 @@ class SettingsComponent extends React.Component {      );    } -  bindForm(name, value) { +  bindForm(name: string, value: any) {      let settings = {        source: this.props.source,        json: this.props.json, @@ -117,22 +127,20 @@ class SettingsComponent extends React.Component {      this.props.dispatch(settingActions.set(settings));    } -  bindJson(e) { +  bindJson(_name: string, value: string) {      let settings = {        source: this.props.source, -      json: e.target.value, +      json: value,        form: this.props.form,      };      this.props.dispatch(settingActions.set(settings));    } -  bindSource(e) { +  bindSource(_name: string, value: string) {      let from = this.props.source; -    let to = e.target.value; - -    if (from === 'form' && to === 'json') { +    if (from === 'form' && value === 'json') {        this.props.dispatch(settingActions.switchToJson(this.props.form)); -    } else if (from === 'json' && to === 'form') { +    } else if (from === 'json' && value === 'form') {        let b = window.confirm(DO_YOU_WANT_TO_CONTINUE);        if (!b) {          this.forceUpdate(); @@ -148,6 +156,6 @@ class SettingsComponent extends React.Component {    }  } -const mapStateToProps = state => state; +const mapStateToProps = (state: any) => state;  export default connect(mapStateToProps)(SettingsComponent); diff --git a/src/settings/components/ui/AddButton.tsx b/src/settings/components/ui/AddButton.tsx index 185a03b..0577068 100644 --- a/src/settings/components/ui/AddButton.tsx +++ b/src/settings/components/ui/AddButton.tsx @@ -1,7 +1,10 @@  import './AddButton.scss';  import React from 'react'; -class AddButton extends React.Component { +interface Props extends React.AllHTMLAttributes<HTMLInputElement> { +} + +class AddButton extends React.Component<Props> {    render() {      return <input        className='ui-add-button' type='button' value='✚' diff --git a/src/settings/components/ui/DeleteButton.tsx b/src/settings/components/ui/DeleteButton.tsx index 75811cd..f0ef6c9 100644 --- a/src/settings/components/ui/DeleteButton.tsx +++ b/src/settings/components/ui/DeleteButton.tsx @@ -1,7 +1,10 @@  import './DeleteButton.scss';  import React from 'react'; -class DeleteButton extends React.Component { +interface Props extends React.AllHTMLAttributes<HTMLInputElement> { +} + +class DeleteButton extends React.Component<Props> {    render() {      return <input        className='ui-delete-button' type='button' value='✖' diff --git a/src/settings/components/ui/Input.tsx b/src/settings/components/ui/Input.tsx index 13a246b..b7593b9 100644 --- a/src/settings/components/ui/Input.tsx +++ b/src/settings/components/ui/Input.tsx @@ -1,34 +1,57 @@  import React from 'react'; -import PropTypes from 'prop-types';  import './Input.scss'; -class Input extends React.Component { +interface Props extends React.AllHTMLAttributes<HTMLElement> { +  name: string; +  type: string; +  error?: string; +  label: string; +  value: string; +  onValueChange?: (name: string, value: string) => void; +  onBlur?: (e: React.FocusEvent<Element>) => void; +} -  renderText(props) { +class Input extends React.Component<Props> { +  renderText(props: Props) {      let inputClassName = props.error ? 'input-error' : ''; +    let pp = { ...props }; +    delete pp.onValueChange;      return <div className='settings-ui-input'>        <label htmlFor={props.id}>{ props.label }</label> -      <input type='text' className={inputClassName} {...props} /> +      <input +        type='text' className={inputClassName} +        onChange={this.bindOnChange.bind(this)} +        { ...pp } />      </div>;    } -  renderRadio(props) { +  renderRadio(props: Props) {      let inputClassName = props.error ? 'input-error' : ''; +    let pp = { ...props }; +    delete pp.onValueChange;      return <div className='settings-ui-input'>        <label> -        <input type='radio' className={inputClassName} {...props} /> +        <input +          type='radio' className={inputClassName} +          onChange={this.bindOnChange.bind(this)} +          { ...pp } />          { props.label }        </label>      </div>;    } -  renderTextArea(props) { +  renderTextArea(props: Props) {      let inputClassName = props.error ? 'input-error' : ''; +    let pp = { ...props }; +    delete pp.onValueChange;      return <div className='settings-ui-input'>        <label          htmlFor={props.id}        >{ props.label }</label> -      <textarea className={inputClassName} {...props} /> +      <textarea +        className={inputClassName} +        onChange={this.bindOnChange.bind(this)} +        { ...pp } />        <p className='settings-ui-input-error'>{ this.props.error }</p>      </div>;    } @@ -48,13 +71,12 @@ class Input extends React.Component {      }      return null;    } -} -Input.propTypes = { -  type: PropTypes.string, -  error: PropTypes.string, -  label: PropTypes.string, -  value: PropTypes.string, -}; +  bindOnChange(e: React.ChangeEvent<HTMLInputElement|HTMLTextAreaElement>) { +    if (this.props.onValueChange) { +      this.props.onValueChange(e.target.name, e.target.value); +    } +  } +}  export default Input; diff --git a/src/settings/reducers/setting.ts b/src/settings/reducers/setting.ts index 54033aa..47c21bf 100644 --- a/src/settings/reducers/setting.ts +++ b/src/settings/reducers/setting.ts @@ -1,13 +1,23 @@ -import actions from 'settings/actions'; +import * as actions from '../actions'; -const defaultState = { +interface State { +  source: string; +  json: string; +  form: any; +  error: string; +} + +const defaultState: State = {    source: '',    json: '',    form: null,    error: '',  }; -export default function reducer(state = defaultState, action = {}) { +export default function reducer( +  state = defaultState, +  action: actions.SettingAction, +) {    switch (action.type) {    case actions.SETTING_SET_SETTINGS:      return { ...state, | 
