This commit is contained in:
Nathan Bierema 2020-10-12 21:00:30 -04:00
parent b2b0fbb6e2
commit d8ddaa4056
24 changed files with 294 additions and 193 deletions

View File

@ -14,3 +14,4 @@ export * from './Toolbar';
import color from './utils/color'; import color from './utils/color';
export const effects = { color }; export const effects = { color };
export { default as createStyledComponent } from './utils/createStyledComponent'; export { default as createStyledComponent } from './utils/createStyledComponent';
export { Theme, Scheme } from './utils/theme';

View File

@ -3,19 +3,22 @@ import { nicinabox as defaultDarkScheme } from 'redux-devtools-themes';
import * as baseSchemes from 'base16'; import * as baseSchemes from 'base16';
import * as additionalSchemes from '../colorSchemes'; import * as additionalSchemes from '../colorSchemes';
import invertColors from '../utils/invertColors'; import invertColors from '../utils/invertColors';
import { Theme } from '../themes/default'; import { Theme as ThemeBase } from '../themes/default';
export const schemes = { ...baseSchemes, ...additionalSchemes }; export const schemes = { ...baseSchemes, ...additionalSchemes };
export const listSchemes = () => Object.keys(schemes).slice(1).sort(); // remove `__esModule` export const listSchemes = () => Object.keys(schemes).slice(1).sort(); // remove `__esModule`
export const listThemes = () => Object.keys(themes); export const listThemes = () => Object.keys(themes);
export type Theme = keyof typeof themes;
export type Scheme = keyof typeof schemes;
export interface ThemeData { export interface ThemeData {
theme: keyof typeof themes; theme: keyof typeof themes;
scheme: keyof typeof schemes; scheme: keyof typeof schemes;
light: boolean; light: boolean;
} }
export interface ThemeFromProvider extends Theme { export interface ThemeFromProvider extends ThemeBase {
type: keyof typeof themes; type: keyof typeof themes;
light: boolean; light: boolean;
} }

View File

@ -20,11 +20,29 @@ import { RECONNECT } from '../constants/socketActionTypes';
let monitorReducer; let monitorReducer;
let monitorProps = {}; let monitorProps = {};
export function changeSection(section) { interface ChangeSectionAction {
readonly type: typeof CHANGE_SECTION;
readonly section: string;
}
export function changeSection(section: string): ChangeSectionAction {
return { type: CHANGE_SECTION, section }; return { type: CHANGE_SECTION, section };
} }
export function changeTheme(data) { interface ChangeThemeFormData {
readonly theme: 'default' | 'material';
readonly scheme: string;
readonly dark: boolean;
}
interface ChangeThemeData {
readonly formData: ChangeThemeFormData;
}
interface ChangeThemeAction {
readonly type: typeof CHANGE_THEME;
readonly theme: 'default' | 'material';
readonly scheme: string;
readonly dark: boolean;
}
export function changeTheme(data: ChangeThemeData): ChangeThemeAction {
return { type: CHANGE_THEME, ...data.formData }; return { type: CHANGE_THEME, ...data.formData };
} }
@ -63,7 +81,10 @@ export function importState(state, preloadedState) {
return { type: LIFTED_ACTION, message: 'IMPORT', state, preloadedState }; return { type: LIFTED_ACTION, message: 'IMPORT', state, preloadedState };
} }
export function exportState() { interface ExportAction {
type: typeof EXPORT;
}
export function exportState(): ExportAction {
return { type: EXPORT }; return { type: EXPORT };
} }
@ -89,34 +110,81 @@ export function dispatchRemotely(action) {
return { type: LIFTED_ACTION, message: 'ACTION', action }; return { type: LIFTED_ACTION, message: 'ACTION', action };
} }
export function togglePersist() { interface TogglePersistAction {
type: typeof TOGGLE_PERSIST;
}
export function togglePersist(): TogglePersistAction {
return { type: TOGGLE_PERSIST }; return { type: TOGGLE_PERSIST };
} }
export function toggleSync() { interface ToggleSyncAction {
type: typeof TOGGLE_SYNC;
}
export function toggleSync(): ToggleSyncAction {
return { type: TOGGLE_SYNC }; return { type: TOGGLE_SYNC };
} }
export function toggleSlider() { interface ToggleSliderAction {
type: typeof TOGGLE_SLIDER;
}
export function toggleSlider(): ToggleSliderAction {
return { type: TOGGLE_SLIDER }; return { type: TOGGLE_SLIDER };
} }
export function toggleDispatcher() { interface ToggleDispatcherAction {
type: typeof TOGGLE_DISPATCHER;
}
export function toggleDispatcher(): ToggleDispatcherAction {
return { type: TOGGLE_DISPATCHER }; return { type: TOGGLE_DISPATCHER };
} }
export function saveSocketSettings(options) { interface ConnectionOptions {
readonly type: 'disabled' | 'remotedev' | 'custom';
readonly hostname: string;
readonly port: number;
readonly secure: boolean;
}
interface ReconnectAction {
readonly type: typeof RECONNECT;
readonly options: ConnectionOptions;
}
export function saveSocketSettings(
options: ConnectionOptions
): ReconnectAction {
return { type: RECONNECT, options }; return { type: RECONNECT, options };
} }
export function showNotification(message) { interface Notification {
readonly type: 'error';
readonly message: string;
}
interface ShowNotificationAction {
readonly type: typeof SHOW_NOTIFICATION;
readonly notification: Notification;
}
export function showNotification(message: string): ShowNotificationAction {
return { type: SHOW_NOTIFICATION, notification: { type: 'error', message } }; return { type: SHOW_NOTIFICATION, notification: { type: 'error', message } };
} }
export function clearNotification() { interface ClearNotificationAction {
readonly type: typeof CLEAR_NOTIFICATION;
}
export function clearNotification(): ClearNotificationAction {
return { type: CLEAR_NOTIFICATION }; return { type: CLEAR_NOTIFICATION };
} }
export function getReport(report) { export function getReport(report) {
return { type: GET_REPORT_REQUEST, report }; return { type: GET_REPORT_REQUEST, report };
} }
export type StoreAction =
| ChangeSectionAction
| ChangeThemeAction
| ExportAction
| TogglePersistAction
| ToggleSyncAction
| ToggleSliderAction
| ToggleDispatcherAction
| ReconnectAction
| ShowNotificationAction
| ClearNotificationAction;

View File

@ -1,8 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Tabs, Toolbar, Button, Divider } from 'devui'; import { Tabs, Toolbar, Button, Divider } from 'devui';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { GoBook } from 'react-icons/go'; import { GoBook } from 'react-icons/go';
import { IoMdText } from 'react-icons/io'; import { IoMdText } from 'react-icons/io';
import { TiSocialTwitter } from 'react-icons/ti'; import { TiSocialTwitter } from 'react-icons/ti';
@ -11,13 +9,14 @@ import { changeSection } from '../actions';
const tabs = [{ name: 'Actions' }, { name: 'Reports' }, { name: 'Settings' }]; const tabs = [{ name: 'Actions' }, { name: 'Reports' }, { name: 'Settings' }];
class Header extends Component { type DispatchProps = ResolveThunks<typeof actionCreators>;
static propTypes = { interface OwnProps {
section: PropTypes.string.isRequired, readonly section: string;
changeSection: PropTypes.func.isRequired, }
}; type Props = DispatchProps & OwnProps;
openLink = (url) => () => { class Header extends Component<Props> {
openLink = (url: string) => () => {
window.open(url); window.open(url);
}; };
@ -69,10 +68,8 @@ class Header extends Component {
} }
} }
function mapDispatchToProps(dispatch) { const actionCreators = {
return { changeSection,
changeSection: bindActionCreators(changeSection, dispatch), };
};
}
export default connect(null, mapDispatchToProps)(Header); export default connect(null, actionCreators)(Header);

View File

@ -1,17 +1,23 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Select } from 'devui'; import { Select } from 'devui';
import { selectInstance } from '../actions'; import { selectInstance } from '../actions';
import { StoreState } from '../reducers';
class InstanceSelector extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps;
class InstanceSelector extends Component<Props> {
static propTypes = { static propTypes = {
selected: PropTypes.string, selected: PropTypes.string,
instances: PropTypes.object.isRequired, instances: PropTypes.object.isRequired,
onSelect: PropTypes.func.isRequired, onSelect: PropTypes.func.isRequired,
}; };
select?: { readonly value: string; readonly label: string }[];
render() { render() {
this.select = [{ value: '', label: 'Autoselect instances' }]; this.select = [{ value: '', label: 'Autoselect instances' }];
const instances = this.props.instances; const instances = this.props.instances;
@ -19,7 +25,7 @@ class InstanceSelector extends Component {
Object.keys(instances).forEach((key) => { Object.keys(instances).forEach((key) => {
name = instances[key].name; name = instances[key].name;
if (name !== undefined) if (name !== undefined)
this.select.push({ value: key, label: instances[key].name }); this.select!.push({ value: key, label: instances[key].name });
}); });
return ( return (
@ -32,17 +38,13 @@ class InstanceSelector extends Component {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { selected: state.instances.selected,
selected: state.instances.selected, instances: state.instances.options,
instances: state.instances.options, });
};
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { onSelect: selectInstance,
onSelect: bindActionCreators(selectInstance, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(InstanceSelector); export default connect(mapStateToProps, actionCreators)(InstanceSelector);

View File

@ -1,18 +1,22 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Tabs } from 'devui'; import { Tabs } from 'devui';
import { monitors } from '../utils/getMonitor'; import { monitors } from '../utils/getMonitor';
import { selectMonitor } from '../actions'; import { selectMonitor } from '../actions';
import { StoreState } from '../reducers';
class MonitorSelector extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps;
class MonitorSelector extends Component<Props> {
static propTypes = { static propTypes = {
selected: PropTypes.string, selected: PropTypes.string,
selectMonitor: PropTypes.func.isRequired, selectMonitor: PropTypes.func.isRequired,
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps: Props) {
return nextProps.selected !== this.props.selected; return nextProps.selected !== this.props.selected;
} }
@ -30,16 +34,12 @@ class MonitorSelector extends Component {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { selected: state.monitor.selected,
selected: state.monitor.selected, });
};
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { selectMonitor,
selectMonitor: bindActionCreators(selectMonitor, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(MonitorSelector); export default connect(mapStateToProps, actionCreators)(MonitorSelector);

View File

@ -1,9 +1,9 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Container, Form } from 'devui'; import { Container, Form } from 'devui';
import { saveSocketSettings } from '../../actions'; import { saveSocketSettings } from '../../actions';
import { StoreState } from '../../reducers';
const defaultSchema = { const defaultSchema = {
type: 'object', type: 'object',
@ -37,19 +37,17 @@ const uiSchema = {
}, },
}; };
class Connection extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
static propTypes = { type DispatchProps = ResolveThunks<typeof actionCreators>;
saveSettings: PropTypes.func.isRequired, type Props = StateProps & DispatchProps;
options: PropTypes.object.isRequired,
type: PropTypes.string,
};
class Connection extends Component<Props> {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = this.setFormData(props.type); this.state = this.setFormData(props.type);
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps: Props, nextState) {
return this.state !== nextState; return this.state !== nextState;
} }
@ -119,14 +117,10 @@ class Connection extends Component {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => state.connection;
return state.connection;
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { saveSettings: saveSocketSettings,
saveSettings: bindActionCreators(saveSocketSettings, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Connection); export default connect(mapStateToProps, actionCreators)(Connection);

View File

@ -1,17 +1,15 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import { connect, ResolveThunks } from 'react-redux';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Container, Form } from 'devui'; import { Container, Form } from 'devui';
import { listSchemes, listThemes } from 'devui/lib/utils/theme'; import { listSchemes, listThemes } from 'devui/lib/utils/theme';
import { changeTheme } from '../../actions'; import { changeTheme } from '../../actions';
import { StoreState } from '../../reducers';
class Themes extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
static propTypes = { type DispatchProps = ResolveThunks<typeof actionCreators>;
changeTheme: PropTypes.func.isRequired, type Props = StateProps & DispatchProps;
theme: PropTypes.object.isRequired,
};
class Themes extends Component<Props> {
render() { render() {
const theme = this.props.theme; const theme = this.props.theme;
const formData = { const formData = {
@ -49,16 +47,12 @@ class Themes extends Component {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { theme: state.theme,
theme: state.theme, });
};
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { changeTheme,
changeTheme: bindActionCreators(changeTheme, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Themes); export default connect(mapStateToProps, actionCreators)(Themes);

View File

@ -1,18 +1,20 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { FaTerminal } from 'react-icons/fa'; import { FaTerminal } from 'react-icons/fa';
import { toggleDispatcher } from '../../actions'; import { toggleDispatcher } from '../../actions';
class DispatcherButton extends Component { type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = DispatchProps;
class DispatcherButton extends Component<Props> {
static propTypes = { static propTypes = {
dispatcherIsOpen: PropTypes.bool, dispatcherIsOpen: PropTypes.bool,
toggleDispatcher: PropTypes.func.isRequired, toggleDispatcher: PropTypes.func.isRequired,
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps: Props) {
return nextProps.dispatcherIsOpen !== this.props.dispatcherIsOpen; return nextProps.dispatcherIsOpen !== this.props.dispatcherIsOpen;
} }
@ -32,10 +34,8 @@ class DispatcherButton extends Component {
} }
} }
function mapDispatchToProps(dispatch) { const actionCreators = {
return { toggleDispatcher,
toggleDispatcher: bindActionCreators(toggleDispatcher, dispatch), };
};
}
export default connect(null, mapDispatchToProps)(DispatcherButton); export default connect(null, actionCreators)(DispatcherButton);

View File

@ -1,12 +1,14 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { TiDownload } from 'react-icons/ti'; import { TiDownload } from 'react-icons/ti';
import { exportState } from '../../actions'; import { exportState } from '../../actions';
class ExportButton extends Component { type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = DispatchProps;
class ExportButton extends Component<Props> {
static propTypes = { static propTypes = {
exportState: PropTypes.func.isRequired, exportState: PropTypes.func.isRequired,
}; };
@ -24,10 +26,8 @@ class ExportButton extends Component {
} }
} }
function mapDispatchToProps(dispatch) { const actionCreators = {
return { exportState,
exportState: bindActionCreators(exportState, dispatch), };
};
}
export default connect(null, mapDispatchToProps)(ExportButton); export default connect(null, actionCreators)(ExportButton);

View File

@ -1,19 +1,23 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { FaThumbtack } from 'react-icons/fa'; import { FaThumbtack } from 'react-icons/fa';
import { togglePersist } from '../../actions'; import { togglePersist } from '../../actions';
import { StoreState } from '../../reducers';
class LockButton extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps;
class LockButton extends Component<Props> {
static propTypes = { static propTypes = {
persisted: PropTypes.bool, persisted: PropTypes.bool,
disabled: PropTypes.bool, disabled: PropTypes.bool,
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps: Props) {
return nextProps.persisted !== this.props.persisted; return nextProps.persisted !== this.props.persisted;
} }
@ -37,16 +41,12 @@ class LockButton extends Component {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { persisted: state.instances.persisted,
persisted: state.instances.persisted, });
};
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { onClick: togglePersist,
onClick: bindActionCreators(togglePersist, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(LockButton); export default connect(mapStateToProps, actionCreators)(LockButton);

View File

@ -1,18 +1,20 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { MdAvTimer } from 'react-icons/md'; import { MdAvTimer } from 'react-icons/md';
import { toggleSlider } from '../../actions'; import { toggleSlider } from '../../actions';
class SliderButton extends Component { type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = DispatchProps;
class SliderButton extends Component<Props> {
static propTypes = { static propTypes = {
isOpen: PropTypes.bool, isOpen: PropTypes.bool,
toggleSlider: PropTypes.func.isRequired, toggleSlider: PropTypes.func.isRequired,
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps: Props) {
return nextProps.isOpen !== this.props.isOpen; return nextProps.isOpen !== this.props.isOpen;
} }
@ -30,10 +32,8 @@ class SliderButton extends Component {
} }
} }
function mapDispatchToProps(dispatch) { const actionCreators = {
return { toggleSlider,
toggleSlider: bindActionCreators(toggleSlider, dispatch), };
};
}
export default connect(null, mapDispatchToProps)(SliderButton); export default connect(null, actionCreators)(SliderButton);

View File

@ -1,18 +1,22 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { connect, ResolveThunks } from 'react-redux';
import { connect } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { TiArrowSync } from 'react-icons/ti'; import { TiArrowSync } from 'react-icons/ti';
import { toggleSync } from '../../actions'; import { toggleSync } from '../../actions';
import { StoreState } from '../../reducers';
class SyncButton extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps;
class SyncButton extends Component<Props> {
static propTypes = { static propTypes = {
sync: PropTypes.bool, sync: PropTypes.bool,
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps: Props) {
return nextProps.sync !== this.props.sync; return nextProps.sync !== this.props.sync;
} }
@ -30,16 +34,12 @@ class SyncButton extends Component {
} }
} }
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { sync: state.instances.sync,
sync: state.instances.sync, });
};
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { onClick: toggleSync,
onClick: bindActionCreators(toggleSync, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(SyncButton); export default connect(mapStateToProps, actionCreators)(SyncButton);

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Container } from 'devui'; import { Container } from 'devui';
import SliderMonitor from './monitors/Slider'; import SliderMonitor from './monitors/Slider';
@ -10,6 +9,7 @@ import DevTools from '../containers/DevTools';
import Dispatcher from './monitors/Dispatcher'; import Dispatcher from './monitors/Dispatcher';
import TopButtons from '../components/TopButtons'; import TopButtons from '../components/TopButtons';
import BottomButtons from '../components/BottomButtons'; import BottomButtons from '../components/BottomButtons';
import { StoreState } from '../reducers';
class Actions extends Component { class Actions extends Component {
render() { render() {
@ -61,7 +61,7 @@ Actions.propTypes = {
sliderIsOpen: PropTypes.bool, sliderIsOpen: PropTypes.bool,
}; };
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => {
const instances = state.instances; const instances = state.instances;
const id = getActiveInstance(instances); const id = getActiveInstance(instances);
return { return {
@ -73,13 +73,11 @@ function mapStateToProps(state) {
sliderIsOpen: state.monitor.sliderIsOpen, sliderIsOpen: state.monitor.sliderIsOpen,
reports: state.reports.data, reports: state.reports.data,
}; };
} };
function mapDispatchToProps(dispatch) { const actionCreators = {
return { liftedDispatch: liftedDispatchAction,
liftedDispatch: bindActionCreators(liftedDispatchAction, dispatch), getReport,
getReport: bindActionCreators(getReport, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Actions); export default connect(mapStateToProps, actionCreators)(Actions);

View File

@ -1,14 +1,18 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Container, Notification } from 'devui'; import { Container, Notification } from 'devui';
import { clearNotification } from '../actions'; import { clearNotification } from '../actions';
import Header from '../components/Header'; import Header from '../components/Header';
import Actions from '../containers/Actions'; import Actions from '../containers/Actions';
import Settings from '../components/Settings'; import Settings from '../components/Settings';
import { StoreState } from '../reducers';
class App extends Component { type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps;
class App extends Component<Props> {
render() { render() {
const { section, theme, notification } = this.props; const { section, theme, notification } = this.props;
let body; let body;
@ -47,18 +51,14 @@ App.propTypes = {
clearNotification: PropTypes.func, clearNotification: PropTypes.func,
}; };
function mapStateToProps(state) { const mapStateToProps = (state: StoreState) => ({
return { section: state.section,
section: state.section, theme: state.theme,
theme: state.theme, notification: state.notification,
notification: state.notification, });
};
}
function mapDispatchToProps(dispatch) { const actionCreators = {
return { clearNotification,
clearNotification: bindActionCreators(clearNotification, dispatch), };
};
}
export default connect(mapStateToProps, mapDispatchToProps)(App); export default connect(mapStateToProps, actionCreators)(App);

View File

@ -1,11 +1,22 @@
import { RECONNECT } from '../constants/socketActionTypes'; import { RECONNECT } from '../constants/socketActionTypes';
import { StoreAction } from '../actions';
interface ConnectionOptions {
readonly hostname: string;
readonly port: number;
readonly secure: boolean;
}
export interface ConnectionState {
readonly options: ConnectionOptions;
readonly type: 'disabled' | 'remotedev' | 'custom';
}
export default function connection( export default function connection(
state = { state: ConnectionState = {
options: { hostname: 'localhost', port: 8000, secure: false }, options: { hostname: 'localhost', port: 8000, secure: false },
type: 'remotedev', type: 'remotedev',
}, },
action action: StoreAction
) { ) {
if (action.type === RECONNECT) { if (action.type === RECONNECT) {
const { type, ...options } = action.options; const { type, ...options } = action.options;

View File

@ -1,14 +1,22 @@
import { combineReducers } from 'redux'; import { combineReducers } from 'redux';
import section from './section'; import section, { SectionState } from './section';
import connection from './connection'; import connection, { ConnectionState } from './connection';
import socket from './socket'; import socket from './socket';
import monitor from './monitor'; import monitor from './monitor';
import notification from './notification'; import notification, { NotificationState } from './notification';
import instances from './instances'; import instances from './instances';
import reports from './reports'; import reports from './reports';
import theme from './theme'; import theme, { ThemeState } from './theme';
import { StoreAction } from '../actions';
const rootReducer = combineReducers({ export interface StoreState {
readonly section: SectionState;
readonly theme: ThemeState;
readonly connection: ConnectionState;
readonly notification: NotificationState;
}
const rootReducer = combineReducers<StoreState, StoreAction>({
section, section,
theme, theme,
connection, connection,

View File

@ -11,6 +11,8 @@ import { DISCONNECTED } from '../constants/socketActionTypes';
import parseJSON from '../utils/parseJSON'; import parseJSON from '../utils/parseJSON';
import { recompute } from '../utils/updateState'; import { recompute } from '../utils/updateState';
interface InstancesState {}
export const initialState = { export const initialState = {
selected: null, selected: null,
current: 'default', current: 'default',

View File

@ -5,6 +5,7 @@ import {
TOGGLE_SLIDER, TOGGLE_SLIDER,
TOGGLE_DISPATCHER, TOGGLE_DISPATCHER,
} from '../constants/actionTypes'; } from '../constants/actionTypes';
import { StoreAction } from '../actions';
const initialState = { const initialState = {
selected: 'InspectorMonitor', selected: 'InspectorMonitor',
@ -26,7 +27,7 @@ export function dispatchMonitorAction(state, action) {
}; };
} }
export default function monitor(state = initialState, action) { export default function monitor(state = initialState, action: StoreAction) {
switch (action.type) { switch (action.type) {
case MONITOR_ACTION: case MONITOR_ACTION:
return dispatchMonitorAction(state, action); return dispatchMonitorAction(state, action);

View File

@ -4,8 +4,18 @@ import {
LIFTED_ACTION, LIFTED_ACTION,
ERROR, ERROR,
} from '../constants/actionTypes'; } from '../constants/actionTypes';
import { StoreAction } from '../actions';
export default function notification(state = null, action) { interface Notification {
readonly type: 'error';
readonly message: string;
}
export type NotificationState = Notification | null;
export default function notification(
state: NotificationState = null,
action: StoreAction
): NotificationState {
switch (action.type) { switch (action.type) {
case SHOW_NOTIFICATION: case SHOW_NOTIFICATION:
return action.notification; return action.notification;

View File

@ -1,12 +1,13 @@
import { import {
UPDATE_REPORTS /* , GET_REPORT_SUCCESS */, UPDATE_REPORTS /* , GET_REPORT_SUCCESS */,
} from '../constants/actionTypes'; } from '../constants/actionTypes';
import { StoreAction } from '../actions';
const initialState = { const initialState = {
data: [], data: [],
}; };
export default function reports(state = initialState, action) { export default function reports(state = initialState, action: StoreAction) {
/* if (action.type === GET_REPORT_SUCCESS) { /* if (action.type === GET_REPORT_SUCCESS) {
const id = action.data.id; const id = action.data.id;
return { return {

View File

@ -1,6 +1,9 @@
import { CHANGE_SECTION } from '../constants/actionTypes'; import { CHANGE_SECTION } from '../constants/actionTypes';
import { StoreAction } from '../actions';
export default function section(state = 'Actions', action) { export type SectionState = string;
export default function section(state = 'Actions', action: StoreAction) {
if (action.type === CHANGE_SECTION) { if (action.type === CHANGE_SECTION) {
return action.section; return action.section;
} }

View File

@ -1,4 +1,5 @@
import * as actions from '../constants/socketActionTypes'; import * as actions from '../constants/socketActionTypes';
import { StoreAction } from '../actions';
const initialState = { const initialState = {
id: null, id: null,
@ -9,7 +10,7 @@ const initialState = {
error: undefined, error: undefined,
}; };
export default function socket(state = initialState, action) { export default function socket(state = initialState, action: StoreAction) {
switch (action.type) { switch (action.type) {
case actions.CONNECT_REQUEST: { case actions.CONNECT_REQUEST: {
return { return {

View File

@ -1,8 +1,15 @@
import { CHANGE_THEME } from '../constants/actionTypes'; import { CHANGE_THEME } from '../constants/actionTypes';
import { StoreAction } from '../actions';
export interface ThemeState {
readonly theme: 'default' | 'material';
readonly scheme: string;
readonly light: boolean;
}
export default function theme( export default function theme(
state = { theme: 'default', scheme: 'default', light: true }, state = { theme: 'default', scheme: 'default', light: true },
action action: StoreAction
) { ) {
if (action.type === CHANGE_THEME) { if (action.type === CHANGE_THEME) {
return { return {