Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Refactoring #16

Merged
merged 42 commits into from
Sep 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8feec76
Implement routing
zalmoxisus Sep 3, 2016
067d62d
Implement navigation
zalmoxisus Sep 3, 2016
f65c082
Fix styles
zalmoxisus Sep 4, 2016
d2f2f4b
Pass props to the child container
zalmoxisus Sep 5, 2016
6ffc706
Redux store with a noop reducer
zalmoxisus Sep 5, 2016
ac7cd8c
Implement `react-router-redux`
zalmoxisus Sep 5, 2016
0c1c906
Fetch reports / logs
zalmoxisus Sep 6, 2016
a48c07b
Socket API middleware
zalmoxisus Sep 6, 2016
afe1b8f
Lifting states reducer
zalmoxisus Sep 6, 2016
0d49d96
Merge branch 'master' into logs
zalmoxisus Sep 6, 2016
03b315f
Implement `instances` reducer
zalmoxisus Sep 7, 2016
96b9545
Emit socket messages to start monitoring
zalmoxisus Sep 7, 2016
f45ea7a
Remove `redux-devtools` dependency
zalmoxisus Sep 7, 2016
1d2c310
Select instances
zalmoxisus Sep 7, 2016
d9fc507
Lifted states and actions
zalmoxisus Sep 7, 2016
4975d5c
Better handling of connections
zalmoxisus Sep 8, 2016
c686e7f
Unify `instances` reducers
zalmoxisus Sep 9, 2016
ccf5463
Handle dispatch actions from the monitor
zalmoxisus Sep 9, 2016
4279292
Import / export state
zalmoxisus Sep 9, 2016
0c079a4
Refactor dispatcher
zalmoxisus Sep 9, 2016
3619ffe
Refactor syncing
zalmoxisus Sep 9, 2016
2066d83
Support multiple connections
zalmoxisus Sep 9, 2016
8b373b7
Refactor socket settings
zalmoxisus Sep 10, 2016
944a8ba
Persist socket settings
zalmoxisus Sep 10, 2016
f9c6079
Refactor monitor selector
zalmoxisus Sep 10, 2016
43bc52d
Persist slider and dispatcher visibility
zalmoxisus Sep 10, 2016
ad8a8e3
Refactor components
zalmoxisus Sep 10, 2016
5b8a313
Differentiate monitor and devtools actions
zalmoxisus Sep 10, 2016
5c341b7
Show notifications and error messages
zalmoxisus Sep 10, 2016
7e9f008
List and import reports
zalmoxisus Sep 11, 2016
e92a026
Cache imported reports
zalmoxisus Sep 11, 2016
e779404
Optimize monitors updating
zalmoxisus Sep 11, 2016
4ad5dfa
Remove router for now
zalmoxisus Sep 12, 2016
49a8553
Pass instance id in action object
zalmoxisus Sep 13, 2016
c3d974f
Fix persisting monitor options
zalmoxisus Sep 13, 2016
6a92b79
Fix codemirror issue
zalmoxisus Sep 13, 2016
f2b3618
Identify other than Redux libs
zalmoxisus Sep 13, 2016
a3994bb
Refactor test generator
zalmoxisus Sep 13, 2016
93b810a
Add `ERROR` action for notification reducer
zalmoxisus Sep 14, 2016
e1ec761
Add `getActiveInstance` selector
zalmoxisus Sep 14, 2016
fe18294
Refactor `nonReduxDispatch`
zalmoxisus Sep 15, 2016
983fdf7
Pick first instance when disconnected the current one
zalmoxisus Sep 15, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"react": "^15.2.1",
"react-addons-test-utils": "^15.2.1",
"react-dom": "^15.2.1",
"react-router": "^2.6.1",
"react-transform-catch-errors": "^1.0.0",
"react-transform-hmr": "^1.0.1",
"redbox-react": "^1.2.0",
Expand All @@ -92,10 +93,10 @@
"material-ui": "0.15.3",
"react-icons": "^2.2.1",
"react-redux": "^4.0.6",
"react-router-redux": "^4.0.5",
"react-switcher": "^1.0.2",
"react-tap-event-plugin": "^1.0.0",
"redux": "^3.0.5",
"redux-devtools": "^3.2.0",
"redux-devtools-chart-monitor": "^1.4.1",
"redux-devtools-inspector": "^0.7.1",
"redux-devtools-log-monitor": "^1.0.11",
Expand Down
55 changes: 55 additions & 0 deletions src/app/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
LIFTED_ACTION, MONITOR_ACTION, SELECT_INSTANCE, SELECT_MONITOR,
TOGGLE_SYNC, TOGGLE_SLIDER, TOGGLE_DISPATCHER, GET_REPORT_REQUEST,
SHOW_NOTIFICATION, CLEAR_NOTIFICATION
} from '../constants/actionTypes';
import { RECONNECT } from '../constants/socketActionTypes';

export function liftedDispatch(action) {
if (action.type[0] === '@') return { type: MONITOR_ACTION, action };
return { type: LIFTED_ACTION, message: 'DISPATCH', action };
}

export function selectInstance(event, index, selected) {
return { type: SELECT_INSTANCE, selected };
}

export function selectMonitor(event, index, value) {
return { type: SELECT_MONITOR, monitor: value };
}

export function importState(state) {
return { type: LIFTED_ACTION, message: 'IMPORT', state };
}

export function dispatchRemotely(action) {
return { type: LIFTED_ACTION, message: 'ACTION', action };
}

export function toggleSync() {
return { type: TOGGLE_SYNC };
}

export function toggleSlider() {
return { type: TOGGLE_SLIDER };
}

export function toggleDispatcher() {
return { type: TOGGLE_DISPATCHER };
}

export function saveSocketSettings(isCustom, options) {
return { type: RECONNECT, isCustom, options };
}

export function showNotification(message) {
return { type: SHOW_NOTIFICATION, notification: { type: 'ERROR', message } };
}

export function clearNotification() {
return { type: CLEAR_NOTIFICATION };
}

export function getReport(report) {
return { type: GET_REPORT_REQUEST, report };
}
27 changes: 6 additions & 21 deletions src/app/components/ButtonBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,15 @@ import Settings from './Settings';

export default class ButtonBar extends Component {
static propTypes = {
openModal: PropTypes.func.isRequired,
toggleDispatcher: PropTypes.func.isRequired,
toggleSlider: PropTypes.func.isRequired,
liftedState: PropTypes.object.isRequired,
dispatcherIsOpen: PropTypes.bool,
sliderIsOpen: PropTypes.bool,
closeModal: PropTypes.func.isRequired,
saveSettings: PropTypes.func.isRequired,
importState: PropTypes.func.isRequired,
exportState: PropTypes.func.isRequired,
socketOptions: PropTypes.object,
noSettings: PropTypes.bool
};

constructor() {
super();
this.state = { settingsOpened: false };

this.openSettings = this.openSettings.bind(this);
this.closeSettings = this.closeSettings.bind(this);
}
Expand All @@ -53,23 +45,16 @@ export default class ButtonBar extends Component {
render() {
return (
<div style={styles.buttonBar}>
<DispatcherButton
dispatcherIsOpen={this.props.dispatcherIsOpen} onClick={this.props.toggleDispatcher}
/>
<SliderButton isOpen={this.props.sliderIsOpen} onClick={this.props.toggleSlider} />
<ImportButton importState={this.props.importState} />
<ExportButton exportState={this.props.exportState} />
<DispatcherButton dispatcherIsOpen={this.props.dispatcherIsOpen} />
<SliderButton isOpen={this.props.sliderIsOpen}/>
<ImportButton />
<ExportButton liftedState={this.props.liftedState} />
{!this.props.noSettings &&
<Button Icon={SettingsIcon} onClick={this.openSettings}>Settings</Button>
}
<Button Icon={HelpIcon} onClick={this.openHelp}>How to use</Button>
{!this.props.noSettings &&
<Settings
isOpen={this.state.settingsOpened}
close={this.closeSettings}
saveSettings={this.props.saveSettings}
socketOptions={this.props.socketOptions}
/>
<Settings isOpen={this.state.settingsOpened} close={this.closeSettings} />
}
</div>
);
Expand Down
21 changes: 19 additions & 2 deletions src/app/components/Instances.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import shallowCompare from 'react/lib/shallowCompare';
import { selectInstance } from '../actions';
import styles from '../styles';

export default class Instances extends Component {
class Instances extends Component {
static propTypes = {
selected: PropTypes.string,
instances: PropTypes.object.isRequired,
Expand All @@ -18,7 +21,7 @@ export default class Instances extends Component {
render() {
this.select = [['Autoselect instances', null]];
Object.keys(this.props.instances).forEach(key => {
this.select.push([this.props.instances[key], key]);
this.select.push([this.props.instances[key].name, key]);
});

return (
Expand All @@ -38,3 +41,17 @@ export default class Instances extends Component {
);
}
}

function mapStateToProps(state) {
return {
instances: state.instances.options
};
}

function mapDispatchToProps(dispatch) {
return {
onSelect: bindActionCreators(selectInstance, dispatch)
};
}

export default connect(mapStateToProps, mapDispatchToProps)(Instances);
27 changes: 20 additions & 7 deletions src/app/components/MonitorSelector.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import { sideMonitors } from '../containers/DevTools';
import { monitors } from '../containers/getMonitor';
import { selectMonitor } from '../actions';
import styles from '../styles';

export default class MonitorSelector extends Component {
class MonitorSelector extends Component {
static propTypes = {
selected: PropTypes.string,
onSelect: PropTypes.func.isRequired
selectMonitor: PropTypes.func.isRequired
};

items = monitors.map((item, i) =>
<MenuItem key={i} value={item.key} primaryText={item.title} />
);

shouldComponentUpdate(nextProps) {
return nextProps.selected !== this.props.selected;
}
Expand All @@ -20,13 +27,19 @@ export default class MonitorSelector extends Component {
style={styles.select}
labelStyle={styles.selectLabel}
iconStyle={styles.selectIcon}
onChange={this.props.onSelect}
onChange={this.props.selectMonitor}
value={this.props.selected || 'InspectorMonitor'}
>
{sideMonitors.map((item, i) =>
<MenuItem key={i} value={item.key} primaryText={item.title} />
)}
{this.items}
</SelectField>
);
}
}

function mapDispatchToProps(dispatch) {
return {
selectMonitor: bindActionCreators(selectMonitor, dispatch)
};
}

export default connect(null, mapDispatchToProps)(MonitorSelector);
59 changes: 59 additions & 0 deletions src/app/components/Notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as themes from 'redux-devtools-themes';
import { clearNotification } from '../actions';

class Notification extends Component {
static propTypes = {
notification: PropTypes.shape({
message: PropTypes.string,
type: PropTypes.string
}),
clearNotification: PropTypes.func.isRequired
};

shouldComponentUpdate(nextProps) {
return nextProps.notification !== this.props.notification;
}

render() {
if (!this.props.notification) return null;
const theme = themes.nicinabox;
const buttonStyle = {
color: theme.base06, backgroundColor: theme.base00,
margin: '0', background: '#DC2424'
};
const containerStyle = {
color: theme.base06, background: '#FC2424',
padding: '5px 10px', minHeight: '20px', display: 'flex'
};
return (
<div style={containerStyle}>
<div style={{ flex: '1', alignItems: 'center' }}>
<p style={{ margin: '0px' }}>{this.props.notification.message}</p>
</div>
<div style={{ alignItems: 'center' }}>
<button
onClick={this.props.clearNotification}
style={buttonStyle}
>&times;</button>
</div>
</div>
);
}
}

function mapStateToProps(state) {
return {
notification: state.notification
};
}

function mapDispatchToProps(dispatch) {
return {
clearNotification: bindActionCreators(clearNotification, dispatch)
};
}

export default connect(mapStateToProps, mapDispatchToProps)(Notification);
39 changes: 28 additions & 11 deletions src/app/components/Settings.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import Checkbox from 'material-ui/Checkbox';
import TextField from 'material-ui/TextField';
import { saveSocketSettings } from '../actions';
import styles from '../styles';

export default class Settings extends Component {
class Settings extends Component {
static propTypes = {
isOpen: PropTypes.bool,
close: PropTypes.func.isRequired,
saveSettings: PropTypes.func.isRequired,
socketOptions: PropTypes.object
socketOptions: PropTypes.object.isRequired,
isCustom: PropTypes.bool
};

constructor(props) {
super(props);
let isLocal;
const isCustom = props.isCustom;
this.options = {};
if (props.socketOptions) {
isLocal = true;
if (isCustom) {
this.options.hostname = props.socketOptions.hostname;
this.options.port = props.socketOptions.port;
this.options.secure = props.socketOptions.secure;
} else {
isLocal = false;
this.options.hostname = 'localhost';
this.options.port = '8000';
this.options.secure = false;
}

this.state = { isLocal };
this.state = { isCustom };
}

handleLocalChecked = (e, checked) => {
this.setState({ isLocal: checked });
this.setState({ isCustom: checked });
};

handleInputChange = (e, value) => {
Expand All @@ -45,7 +47,7 @@ export default class Settings extends Component {
};

save = () => {
this.props.saveSettings(this.state.isLocal, this.options);
this.props.saveSettings(this.state.isCustom, this.options);
this.props.close();
};

Expand Down Expand Up @@ -77,10 +79,10 @@ export default class Settings extends Component {
>
<Checkbox
label="Use custom (local) server"
checked={this.state.isLocal}
checked={this.state.isCustom}
onCheck={this.handleLocalChecked}
/>
{this.state.isLocal && <div>
{this.state.isCustom && <div>
<TextField
id="hostname"
floatingLabelText="Host name"
Expand All @@ -104,3 +106,18 @@ export default class Settings extends Component {
);
}
}

function mapStateToProps(state) {
return {
socketOptions: state.socket.options,
isCustom: state.socket.isCustom
};
}

function mapDispatchToProps(dispatch) {
return {
saveSettings: bindActionCreators(saveSocketSettings, dispatch)
};
}

export default connect(mapStateToProps, mapDispatchToProps)(Settings);
Loading