diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2019-05-05 08:03:29 +0900 |
---|---|---|
committer | Shin'ya Ueoka <ueokande@i-beam.org> | 2019-05-06 22:17:18 +0900 |
commit | a0882bbceb7ed71d56bf8557620449fbc3f19749 (patch) | |
tree | f2087d44f21dd68fc3584f62cfb9b62ae58bab2b /src/settings/components | |
parent | d01db82c0dca352de2d7644c383d388fc3ec0366 (diff) |
Declare setting types
Diffstat (limited to 'src/settings/components')
-rw-r--r-- | src/settings/components/form/KeymapsForm.tsx | 23 | ||||
-rw-r--r-- | src/settings/components/form/SearchForm.tsx | 30 | ||||
-rw-r--r-- | src/settings/components/index.tsx | 104 |
3 files changed, 91 insertions, 66 deletions
diff --git a/src/settings/components/form/KeymapsForm.tsx b/src/settings/components/form/KeymapsForm.tsx index ab44464..ad4d0e7 100644 --- a/src/settings/components/form/KeymapsForm.tsx +++ b/src/settings/components/form/KeymapsForm.tsx @@ -2,32 +2,30 @@ import './KeymapsForm.scss'; import React from 'react'; import Input from '../ui/Input'; import keymaps from '../../keymaps'; +import { FormKeymaps } from '../../../shared/SettingData'; -type Value = {[key: string]: string}; - -interface Props{ - value: Value; - onChange: (e: Value) => void; +interface Props { + value: FormKeymaps; + onChange: (e: FormKeymaps) => void; onBlur: () => void; } class KeymapsForm extends React.Component<Props> { public static defaultProps: Props = { - value: {}, + value: FormKeymaps.valueOf({}), onChange: () => {}, onBlur: () => {}, } render() { + let values = this.props.value.toJSON(); return <div className='form-keymaps-form'> { keymaps.fields.map((group, index) => { return <div key={index} className='form-keymaps-form-field-group'> { - group.map((field) => { - let name = field[0]; - let label = field[1]; - let value = this.props.value[name] || ''; + group.map(([name, label]) => { + let value = values[name] || ''; return <Input type='text' id={name} name={name} key={name} label={label} value={value} @@ -43,10 +41,7 @@ class KeymapsForm extends React.Component<Props> { } bindValue(name: string, value: string) { - let next = { ...this.props.value }; - next[name] = value; - - this.props.onChange(next); + this.props.onChange(this.props.value.buildWithOverride(name, value)); } } diff --git a/src/settings/components/form/SearchForm.tsx b/src/settings/components/form/SearchForm.tsx index 737e291..67dbeba 100644 --- a/src/settings/components/form/SearchForm.tsx +++ b/src/settings/components/form/SearchForm.tsx @@ -2,31 +2,23 @@ import './SearchForm.scss'; import React from 'react'; import AddButton from '../ui/AddButton'; import DeleteButton from '../ui/DeleteButton'; - -interface Value { - default: string; - engines: string[][]; -} +import { FormSearch } from '../../../shared/SettingData'; interface Props { - value: Value; - onChange: (value: Value) => void; + value: FormSearch; + onChange: (value: FormSearch) => void; onBlur: () => void; } class SearchForm extends React.Component<Props> { public static defaultProps: Props = { - value: { default: '', engines: []}, + value: FormSearch.valueOf({ default: '', engines: []}), onChange: () => {}, onBlur: () => {}, } render() { - let value = this.props.value; - if (!value.engines) { - value.engines = []; - } - + let value = this.props.value.toJSON(); return <div className='form-search-form'> <div className='form-search-form-header'> <div className='column-name'>Name</div> @@ -63,28 +55,28 @@ class SearchForm extends React.Component<Props> { } bindValue(e: any) { - let value = this.props.value; + let value = this.props.value.toJSON(); let name = e.target.name; let index = Number(e.target.getAttribute('data-index')); - let next: Value = { + let next: typeof value = { default: value.default, - engines: value.engines ? value.engines.slice() : [], + engines: value.engines.slice(), }; if (name === 'name') { next.engines[index][0] = e.target.value; - next.default = this.props.value.engines[index][0]; + next.default = value.engines[index][0]; } else if (name === 'url') { next.engines[index][1] = e.target.value; } else if (name === 'default') { - next.default = this.props.value.engines[index][0]; + next.default = value.engines[index][0]; } else if (name === 'add') { next.engines.push(['', '']); } else if (name === 'delete') { next.engines.splice(index, 1); } - this.props.onChange(next); + this.props.onChange(FormSearch.valueOf(next)); if (name === 'delete' || name === 'default') { this.props.onBlur(); } diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx index f56e93f..b4a0866 100644 --- a/src/settings/components/index.tsx +++ b/src/settings/components/index.tsx @@ -6,22 +6,26 @@ 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 SettingData, { + JSONSettings, FormKeymaps, FormSearch, FormSettings, +} from '../../shared/SettingData'; +import { State as AppState } from '../reducers/setting'; +import * as settings from '../../shared/Settings'; +import * as PropertyDefs from '../../shared/property-defs'; const DO_YOU_WANT_TO_CONTINUE = 'Some settings in JSON can be lost when migrating. ' + 'Do you want to continue?'; -interface Props { - source: string; - json: string; - form: any; - error: string; - +type StateProps = ReturnType<typeof mapStateToProps>; +interface DispatchProps { + dispatch: (action: any) => void, +} +type Props = StateProps & DispatchProps & { // FIXME store: any; -} +}; class SettingsComponent extends React.Component<Props> { componentDidMount() { @@ -29,12 +33,17 @@ class SettingsComponent extends React.Component<Props> { } renderFormFields(form: any) { + let types = PropertyDefs.defs.reduce( + (o: {[key: string]: string}, def) => { + o[def.name] = def.type; + return o; + }, {}); return <div> <fieldset> <legend>Keybindings</legend> <KeymapsForm value={form.keymaps} - onChange={value => this.bindForm('keymaps', value)} + onChange={this.bindKeymapsForm.bind(this)} onBlur={this.save.bind(this)} /> </fieldset> @@ -42,7 +51,7 @@ class SettingsComponent extends React.Component<Props> { <legend>Search Engines</legend> <SearchForm value={form.search} - onChange={value => this.bindForm('search', value)} + onChange={this.bindSearchForm.bind(this)} onBlur={this.save.bind(this)} /> </fieldset> @@ -50,23 +59,23 @@ class SettingsComponent extends React.Component<Props> { <legend>Blacklist</legend> <BlacklistForm value={form.blacklist} - onChange={value => this.bindForm('blacklist', value)} + onChange={this.bindBlacklistForm.bind(this)} onBlur={this.save.bind(this)} /> </fieldset> <fieldset> <legend>Properties</legend> <PropertiesForm - types={properties.types} + types={types} value={form.properties} - onChange={value => this.bindForm('properties', value)} + onChange={this.bindPropertiesForm.bind(this)} onBlur={this.save.bind(this)} /> </fieldset> </div>; } - renderJsonFields(json: string, error: string) { + renderJsonFields(json: JSONSettings, error: string) { return <div> <Input type='textarea' @@ -76,7 +85,7 @@ class SettingsComponent extends React.Component<Props> { error={error} onValueChange={this.bindJson.bind(this)} onBlur={this.save.bind(this)} - value={json} + value={json.toJSON()} /> </div>; } @@ -87,7 +96,8 @@ class SettingsComponent extends React.Component<Props> { if (this.props.source === 'form') { fields = this.renderFormFields(this.props.form); } else if (this.props.source === 'json') { - fields = this.renderJsonFields(this.props.json, this.props.error); + fields = this.renderJsonFields( + this.props.json as JSONSettings, this.props.error); } return ( <div> @@ -117,45 +127,73 @@ class SettingsComponent extends React.Component<Props> { ); } - bindForm(name: string, value: any) { - let settings = { + bindKeymapsForm(value: FormKeymaps) { + let data = new SettingData({ + source: this.props.source, + form: (this.props.form as FormSettings).buildWithKeymaps(value), + }); + this.props.dispatch(settingActions.set(data)); + } + + bindSearchForm(value: any) { + let data = new SettingData({ + source: this.props.source, + form: (this.props.form as FormSettings).buildWithSearch( + FormSearch.valueOf(value)), + }); + this.props.dispatch(settingActions.set(data)); + } + + bindBlacklistForm(value: any) { + let data = new SettingData({ + source: this.props.source, + form: (this.props.form as FormSettings).buildWithBlacklist( + settings.blacklistValueOf(value)), + }); + this.props.dispatch(settingActions.set(data)); + } + + bindPropertiesForm(value: any) { + let data = new SettingData({ source: this.props.source, - json: this.props.json, - form: { ...this.props.form }, - }; - settings.form[name] = value; - this.props.dispatch(settingActions.set(settings)); + form: (this.props.form as FormSettings).buildWithProperties( + settings.propertiesValueOf(value)), + }); + this.props.dispatch(settingActions.set(data)); } bindJson(_name: string, value: string) { - let settings = { + let data = new SettingData({ source: this.props.source, - json: value, - form: this.props.form, - }; - this.props.dispatch(settingActions.set(settings)); + json: JSONSettings.valueOf(value), + }); + this.props.dispatch(settingActions.set(data)); } bindSource(_name: string, value: string) { let from = this.props.source; if (from === 'form' && value === 'json') { - this.props.dispatch(settingActions.switchToJson(this.props.form)); + this.props.dispatch(settingActions.switchToJson( + this.props.form as FormSettings)); } else if (from === 'json' && value === 'form') { let b = window.confirm(DO_YOU_WANT_TO_CONTINUE); if (!b) { this.forceUpdate(); return; } - this.props.dispatch(settingActions.switchToForm(this.props.json)); + this.props.dispatch( + settingActions.switchToForm(this.props.json as JSONSettings)); } } save() { - let settings = this.props.store.getState(); - this.props.dispatch(settingActions.save(settings)); + let { source, json, form } = this.props.store.getState(); + this.props.dispatch(settingActions.save( + new SettingData({ source, json, form }), + )); } } -const mapStateToProps = (state: any) => state; +const mapStateToProps = (state: AppState) => ({ ...state }); export default connect(mapStateToProps)(SettingsComponent); |