From fc0af4fc882a6a41dc0fba6ccffc460b16472304 Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Sun, 17 Sep 2017 03:40:04 +0300 Subject: [PATCH] Reduce code repetion in settings --- .../settings/settings.appInfoPanel.js | 132 ++++----- .../components/dashboard/settings/settings.js | 113 +------- .../dashboard/settings/settings.panel.js | 86 ++++++ .../dashboard/settings/settings.panelBody.js | 85 ++++++ .../dashboard/settings/settings.panelUtils.js | 48 ++++ .../dashboard/settings/settings.render.js | 260 ++++++------------ .../settings/settings.walletInfoPanel.js | 4 +- 7 files changed, 372 insertions(+), 356 deletions(-) create mode 100644 react/src/components/dashboard/settings/settings.panel.js create mode 100644 react/src/components/dashboard/settings/settings.panelBody.js create mode 100644 react/src/components/dashboard/settings/settings.panelUtils.js diff --git a/react/src/components/dashboard/settings/settings.appInfoPanel.js b/react/src/components/dashboard/settings/settings.appInfoPanel.js index 030caf4..5453490 100644 --- a/react/src/components/dashboard/settings/settings.appInfoPanel.js +++ b/react/src/components/dashboard/settings/settings.appInfoPanel.js @@ -8,76 +8,82 @@ class AppInfoPanel extends React.Component { } render() { - return ( -
-
-
-
{ translate('SETTINGS.APP_RELEASE') }
-
- { translate('SETTINGS.NAME') }: { this.props.Settings.appInfo.releaseInfo.name } -
-
- { translate('SETTINGS.VERSION') }: { `${this.props.Settings.appInfo.releaseInfo.version.replace('version=', '')}-beta` } -
-
- { translate('SETTINGS.APP_SESSION') }: { this.props.Settings.appInfo.appSession } + const releaseInfo = this.props.Settings.appInfo && this.props.Settings.appInfo.releaseInfo; + + if (!releaseInfo) { + return null + } else { + return ( +
+
+
+
{ translate('SETTINGS.APP_RELEASE') }
+
+ { translate('SETTINGS.NAME') }: { this.props.Settings.appInfo.releaseInfo.name } +
+
+ { translate('SETTINGS.VERSION') }: { `${this.props.Settings.appInfo.releaseInfo.version.replace('version=', '')}-beta` } +
+
+ { translate('SETTINGS.APP_SESSION') }: { this.props.Settings.appInfo.appSession } +
-
-
-
-
{ translate('SETTINGS.SYS_INFO') }
-
- { translate('SETTINGS.ARCH') }: { this.props.Settings.appInfo.sysInfo.arch } -
-
- { translate('SETTINGS.OS_TYPE') }: { this.props.Settings.appInfo.sysInfo.os_type } -
-
- { translate('SETTINGS.OS_PLATFORM') }: { this.props.Settings.appInfo.sysInfo.platform } -
-
- { translate('SETTINGS.OS_RELEASE') }: { this.props.Settings.appInfo.sysInfo.os_release } -
-
- { translate('SETTINGS.CPU') }: { this.props.Settings.appInfo.sysInfo.cpu } -
-
- { translate('SETTINGS.CPU_CORES') }: { this.props.Settings.appInfo.sysInfo.cpu_cores } -
-
- { translate('SETTINGS.MEM') }: { this.props.Settings.appInfo.sysInfo.totalmem_readable } +
+
+
{ translate('SETTINGS.SYS_INFO') }
+
+ { translate('SETTINGS.ARCH') }: { this.props.Settings.appInfo.sysInfo.arch } +
+
+ { translate('SETTINGS.OS_TYPE') }: { this.props.Settings.appInfo.sysInfo.os_type } +
+
+ { translate('SETTINGS.OS_PLATFORM') }: { this.props.Settings.appInfo.sysInfo.platform } +
+
+ { translate('SETTINGS.OS_RELEASE') }: { this.props.Settings.appInfo.sysInfo.os_release } +
+
+ { translate('SETTINGS.CPU') }: { this.props.Settings.appInfo.sysInfo.cpu } +
+
+ { translate('SETTINGS.CPU_CORES') }: { this.props.Settings.appInfo.sysInfo.cpu_cores } +
+
+ { translate('SETTINGS.MEM') }: { this.props.Settings.appInfo.sysInfo.totalmem_readable } +
-
-
-
-
{ translate('SETTINGS.LOCATIONS') }
-
- { translate('SETTINGS.CACHE') }: { this.props.Settings.appInfo.dirs.cacheLocation } -
-
- { translate('SETTINGS.CONFIG') }: { this.props.Settings.appInfo.dirs.configLocation } -
-
- Iguana { translate('SETTINGS.BIN') }: { this.props.Settings.appInfo.dirs.iguanaBin } -
-
- Iguana { translate('SETTINGS.DIR') }: { this.props.Settings.appInfo.dirs.iguanaDir } -
-
- Komodo { translate('SETTINGS.BIN') }: { this.props.Settings.appInfo.dirs.komododBin } -
-
- Komodo { translate('SETTINGS.DIR') }: { this.props.Settings.appInfo.dirs.komodoDir } -
-
- Komodo wallet.dat: { this.props.Settings.appInfo.dirs.komodoDir } +
+
+
{ translate('SETTINGS.LOCATIONS') }
+
+ { translate('SETTINGS.CACHE') }: { this.props.Settings.appInfo.dirs.cacheLocation } +
+
+ { translate('SETTINGS.CONFIG') }: { this.props.Settings.appInfo.dirs.configLocation } +
+
+ Iguana { translate('SETTINGS.BIN') }: { this.props.Settings.appInfo.dirs.iguanaBin } +
+
+ Iguana { translate('SETTINGS.DIR') }: { this.props.Settings.appInfo.dirs.iguanaDir } +
+
+ Komodo { translate('SETTINGS.BIN') }: { this.props.Settings.appInfo.dirs.komododBin } +
+
+ Komodo { translate('SETTINGS.DIR') }: { this.props.Settings.appInfo.dirs.komodoDir } +
+
+ Komodo wallet.dat: { this.props.Settings.appInfo.dirs.komodoDir } +
-
- ); + ); + } }; } diff --git a/react/src/components/dashboard/settings/settings.js b/react/src/components/dashboard/settings/settings.js index f7d0979..25a37e2 100644 --- a/react/src/components/dashboard/settings/settings.js +++ b/react/src/components/dashboard/settings/settings.js @@ -1,15 +1,10 @@ import React from 'react'; import { connect } from 'react-redux'; import { translate } from '../../../translate/translate'; -import Config from '../../../config'; import { iguanaActiveHandle, getAppConfig, - getPeersList, - addPeerNode, getAppInfo, - shepherdCli, - triggerToaster, } from '../../../actions/actionCreators'; import Store from '../../../store'; @@ -17,19 +12,6 @@ import { SettingsRender, } from './settings.render'; -import AppUpdatePanel from './settings.appUpdatePanel'; -import AppInfoPanel from './settings.appInfoPanel'; -import AddNodePanel from './settings.addNodePanel'; -import AppSettingsPanel from './settings.appSettingsPanel'; -import CliPanel from './settings.cliPanel'; -import DebugLogPanel from './settings.debugLogPanel'; -import FiatCurrencyPanel from './settings.fiatCurrencyPanel'; -import ExportKeysPanel from './settings.exportKeysPanel'; -import ImportKeysPanel from './settings.importKeysPanel'; -import SupportPanel from './settings.supportPanel'; -import WalletInfoPanel from './settings.walletInfoPanel'; -import WalletBackupPanel from './settings.walletBackupPanel'; - /* TODO: 1) pre-select active coin in add node tab @@ -38,105 +20,20 @@ import WalletBackupPanel from './settings.walletBackupPanel'; 4) batch export/import wallet addresses */ class Settings extends React.Component { - constructor() { - super(); - this.state = { - activeTab: 0, - tabElId: null, - seedInputVisibility: false, - nativeOnly: Config.iguanaLessMode, - disableWalletSpecificUI: false, - }; - this.updateInput = this.updateInput.bind(this); + constructor(props) { + super(props); } componentDidMount(props) { if (!this.props.disableWalletSpecificUI) { Store.dispatch(iguanaActiveHandle()); } - Store.dispatch(getAppConfig()); Store.dispatch(getAppInfo()); document.getElementById('section-iguana-wallet-settings').setAttribute('style', 'height:auto; min-height: 100%'); } - componentWillReceiveProps(props) { - if (this.state.tabElId) { - this.setState(Object.assign({}, this.state, { - activeTab: this.state.activeTab, - tabElId: this.state.tabElId, - disableWalletSpecificUI: this.props.disableWalletSpecificUI, - })); - } - } - - openTab(elemId, tab) { - this.setState(Object.assign({}, this.state, { - activeTab: tab, - tabElId: elemId, - })); - } - - updateInput(e) { - this.setState({ - [e.target.name]: e.target.value, - }); - } - - renderAppInfoTab() { - const releaseInfo = this.props.Settings.appInfo && this.props.Settings.appInfo.releaseInfo; - - if (releaseInfo) { - return - } - - return null; - } - - renderAppUpdateTab() { - return - } - - renderWalletInfo() { - return - } - renderAddNode() { - return - } - - renderWalletBackup() { - return - } - - renderFiatCurrency() { - return - } - - renderExportKeys() { - return - } - - renderImportKeys() { - return - } - - renderDebugLog() { - return - } - - renderAppSettings() { - return - } - - renderCliPanel() { - return - } - - renderSupportPanel() { - return - } - render() { return SettingsRender.call(this); } @@ -146,13 +43,7 @@ const mapStateToProps = (state) => { return { Main: { coins: state.Main.coins, - activeHandle: state.Main.activeHandle, - }, - ActiveCoin: { - coin: state.ActiveCoin.coin, }, - Settings: state.Settings, - Dashboard: state.Dashboard, }; }; diff --git a/react/src/components/dashboard/settings/settings.panel.js b/react/src/components/dashboard/settings/settings.panel.js new file mode 100644 index 0000000..44f8370 --- /dev/null +++ b/react/src/components/dashboard/settings/settings.panel.js @@ -0,0 +1,86 @@ +import React from 'react'; +import className from 'classnames'; +import * as Utils from './settings.panelUtils'; + +class Panel extends React.Component { + + constructor(props) { + super(props); + this.toggleSection = this.toggleSection.bind(this); + this.state = { + singleOpen: this.props.singleOpen, + openByDefault: this.props.openByDefault, + activeSections: [], + }; + } + + componentWillMount() { + const { + singleOpen, + openByDefault, + uniqId, + children } = this.props; + + const settings = { + singleOpen, + openByDefault, + uniqId, + kids: children + }; + + const initialStateSections = Utils.setupAccordion(settings).activeSections; + this.setState({ activeSections: initialStateSections }); + } + + getChildrenWithProps() { + const { + children, + } = this.props; + + + const kids = React.Children.map(children, (child, i) => { + if(child) { + const unqId = `panel-sec-${i}`; + return React.cloneElement(child, { + toggle: (acId) => this.toggleSection(acId), + key: unqId, + unq: unqId, + active: (this.state.activeSections && this.state.activeSections.lastIndexOf(unqId) !== -1) + }); + } + }); + + + return kids; + } + + toggleSection(sectionId) { + const newActive = Utils.toggleSection( + sectionId, + this.state.activeSections, + this.state.singleOpen); + + this.setState({ + activeSections: newActive + }); + } + + render() { + const { + className: propClasses, + uniqId: propId + } = this.props; + + const childrenWithProps = this.getChildrenWithProps(); + const accordionClasses = className('panel-group', propClasses); + const uniqId = propId || ''; + + return( +
+ {childrenWithProps} +
+ ); + } +} + +export default Panel; \ No newline at end of file diff --git a/react/src/components/dashboard/settings/settings.panelBody.js b/react/src/components/dashboard/settings/settings.panelBody.js new file mode 100644 index 0000000..1997c79 --- /dev/null +++ b/react/src/components/dashboard/settings/settings.panelBody.js @@ -0,0 +1,85 @@ +import React from 'react'; +import className from 'classnames'; + +class PanelSection extends React.Component { + constructor(props) { + super(props); + this.state = { + sectionHeight: 0, + } + this.toggleSection = this.toggleSection.bind(this); + } + + componentDidMount() { + const { active } = this.props; + if (active) this.setState({sectionHeight: this.accordionContent.scrollHeight}); + } + + componentWillReceiveProps(nextProps) { + if(this.props.active) { + this.setState({ + sectionHeight: 'auto', + }); + } + if (nextProps.active !== this.props.active) { + this.toggleOpen(nextProps.active); + } + } + + getHeight() { + const { active } = this.props; + return (active) ? this.accordionContent.scrollHeight : 0; + } + + toggleSection() { + const { + unq, + toggle + } = this.props; + toggle(unq); + } + + toggleOpen(active) { + const height = (active) ? `${this.accordionContent.scrollHeight}px` : 0; + this.setState({ + sectionHeight: height, + }); + } + + render() { + const { + title, + icon, + children, + active, + className: propClasses + } = this.props; + + const contentStyles = { + height: this.state.sectionHeight, + overflow: 'hidden', + transition: 'height .25s ease', + }; + + const contentClasses = className('panel-collapse', { + active + }); + + return( +
this.toggleSection()}> + +
this.accordionContent = ref}> +
+ {children} +
+
+
+ ); + } +} + +export default PanelSection; diff --git a/react/src/components/dashboard/settings/settings.panelUtils.js b/react/src/components/dashboard/settings/settings.panelUtils.js new file mode 100644 index 0000000..e07614f --- /dev/null +++ b/react/src/components/dashboard/settings/settings.panelUtils.js @@ -0,0 +1,48 @@ +export function checkUndef(item) { + return (typeof item !== 'undefined'); +} + +export function toggleSection(sectionId, activeSections, singleOpen) { + let present = null; + let newActiveSections = activeSections; + + newActiveSections.map((section) => { + if (section === sectionId) present = true; + return true; + }); + + if (!singleOpen) { + if (present) { + const pos = newActiveSections.indexOf(sectionId); + newActiveSections.splice(pos, 1); + } else { + newActiveSections.push(sectionId); + } + } else { + newActiveSections = [sectionId]; + } + + return newActiveSections; +} + +export function setupAccordion(info) { + const singleOpen = (checkUndef(info.singleOpen)) ? info.singleOpen : false; + const activeSections = []; + const singleChild = typeof info.kids.length === 'undefined'; + + if (!singleChild) { + info.kids.forEach((child, i) => { + const { openByDefault } = child ? child.props : false; + if (singleOpen && activeSections.length === 0 && openByDefault) { + activeSections.push(`panel-sec-${i}`); + } + if (!singleOpen && openByDefault) { + activeSections.push(`panel-sec-${i}`); + } + }); + } + + return { + activeSections, + }; +} \ No newline at end of file diff --git a/react/src/components/dashboard/settings/settings.render.js b/react/src/components/dashboard/settings/settings.render.js index 4e8d798..6163299 100644 --- a/react/src/components/dashboard/settings/settings.render.js +++ b/react/src/components/dashboard/settings/settings.render.js @@ -1,5 +1,20 @@ import React from 'react'; import { translate } from '../../../translate/translate'; +import PanelSection from './settings.panelBody'; +import Panel from './settings.panel'; + +import AppUpdatePanel from './settings.appUpdatePanel'; +import AppInfoPanel from './settings.appInfoPanel'; +import AddNodePanel from './settings.addNodePanel'; +import AppSettingsPanel from './settings.appSettingsPanel'; +import CliPanel from './settings.cliPanel'; +import DebugLogPanel from './settings.debugLogPanel'; +import FiatCurrencyPanel from './settings.fiatCurrencyPanel'; +import ExportKeysPanel from './settings.exportKeysPanel'; +import ImportKeysPanel from './settings.importKeysPanel'; +import SupportPanel from './settings.supportPanel'; +import WalletInfoPanel from './settings.walletInfoPanel'; +import WalletBackupPanel from './settings.walletBackupPanel'; export const SettingsRender = function() { return ( @@ -12,199 +27,86 @@ export const SettingsRender = function() {

{ translate('INDEX.WALLET_SETTINGS') }

-
- + { !this.props.disableWalletSpecificUI && -
this.openTab('WalletInfo', 0) } - className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }> - -
- { this.renderWalletInfo() } -
-
+ + + } { !this.props.disableWalletSpecificUI && -
this.openTab('AddNodeforCoin', 1) } - className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }> - -
- { this.renderAddNode() } -
-
+ + + } { !this.props.disableWalletSpecificUI && -
this.openTab('DumpWallet', 2) } - className={ 'hide panel' + (this.state.nativeOnly ? ' hide' : '') }> - -
- { this.renderWalletBackup() } -
-
+ + + } { !this.props.disableWalletSpecificUI && -
this.openTab('FiatCurrencySettings', 3) } - className={ 'hide panel' + (this.state.nativeOnly ? ' hide' : '') }> - -
- { this.renderFiatCurrency() } -
-
+ + + } { !this.props.disableWalletSpecificUI && -
this.openTab('ExportKeys', 4) } - className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }> - -
- { this.renderExportKeys() } -
-
+ + + } { !this.props.disableWalletSpecificUI && -
this.openTab('ImportKeys', 5) } - className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }> - -
- { this.renderImportKeys() } -
-
+ + + } - -
this.openTab('DebugLog', 6) }> - -
- { this.renderDebugLog() } -
-
- -
this.openTab('AppSettings', 7) }> - -
- { this.renderAppSettings() } -
-
- -
this.openTab('AppInfo', 8) }> - -
- { this.renderAppInfoTab() } -
-
- + + + + + + + + + { this.props.Main && this.props.Main.coins.native && -
this.openTab('Cli', 9) } - className={ 'panel' + (!this.props.Main.coins.native.length ? ' hide' : '') }> - -
- { this.renderCliPanel() } -
-
+ + + } - -
this.openTab('AppUpdate', 10) }> - -
- { this.renderAppUpdateTab() } -
-
- -
this.openTab('Support', 11) }> - -
- { this.renderSupportPanel() } -
-
-
+ + + + + + +
diff --git a/react/src/components/dashboard/settings/settings.walletInfoPanel.js b/react/src/components/dashboard/settings/settings.walletInfoPanel.js index 29fda9d..ad255f9 100644 --- a/react/src/components/dashboard/settings/settings.walletInfoPanel.js +++ b/react/src/components/dashboard/settings/settings.walletInfoPanel.js @@ -9,8 +9,7 @@ class WalletInfoPanel extends React.Component { render() { return ( -
- +
@@ -44,7 +43,6 @@ class WalletInfoPanel extends React.Component {
{ translate('INDEX.KEY') }
-
); }; }