This commit is contained in:
Nathan Bierema 2020-08-26 23:43:08 -04:00
parent 90dbb8d940
commit 11994b0e95
7 changed files with 77 additions and 37 deletions

View File

@ -2,8 +2,8 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Action, Dispatch } from 'redux';
import * as themes from 'redux-devtools-themes';
import { Base16Theme } from 'redux-devtools-themes';
import { ActionCreators, LiftedAction, LiftedState } from 'redux-devtools';
import { Base16Theme } from 'base16';
import {
updateScrollTop,
startConsecutiveToggle,

View File

@ -1,6 +1,5 @@
import React, { CSSProperties } from 'react';
import { Base16Theme } from 'base16';
import { Action } from 'redux';
import { Base16Theme } from 'redux-devtools-themes';
import brighten from './brighten';
const styles: { base: CSSProperties } = {

View File

@ -1,9 +1,9 @@
import React, { CSSProperties, PureComponent } from 'react';
import PropTypes from 'prop-types';
import { ActionCreators, LiftedAction } from 'redux-devtools';
import LogMonitorButton from './LogMonitorButton';
import { Base16Theme } from 'redux-devtools-themes';
import { Action, Dispatch } from 'redux';
import { Base16Theme } from 'base16';
import LogMonitorButton from './LogMonitorButton';
import { LogMonitorAction } from './actions';
import { LogMonitorState } from './reducers';

View File

@ -1,9 +1,11 @@
import React, { PureComponent } from 'react';
import React, { CSSProperties, MouseEventHandler, PureComponent } from 'react';
import PropTypes from 'prop-types';
import JSONTree from 'react-json-tree';
import JSONTree, { StylingValue } from 'react-json-tree';
import { Base16Theme } from 'redux-devtools-themes';
import { Action } from 'redux';
import LogMonitorEntryAction from './LogMonitorEntryAction';
const styles = {
const styles: { entry: CSSProperties; root: CSSProperties } = {
entry: {
display: 'block',
WebkitUserSelect: 'none',
@ -14,15 +16,40 @@ const styles = {
},
};
const getDeepItem = (data, path) =>
const getDeepItem = (data: any, path: (string | number)[]) =>
path.reduce((obj, key) => obj && obj[key], data);
const dataIsEqual = (data, previousData, keyPath) => {
const dataIsEqual = (
data: any,
previousData: unknown,
keyPath: (string | number)[]
) => {
const path = [...keyPath].reverse().slice(1);
return getDeepItem(data, path) === getDeepItem(previousData, path);
};
export default class LogMonitorEntry extends PureComponent {
interface Props<S, A extends Action<unknown>> {
theme: Base16Theme;
select: (state: any) => unknown;
action: A;
actionId: number;
state: S;
previousState: S | undefined;
collapsed: boolean;
inFuture: boolean;
selected: boolean;
error: string | undefined;
expandActionRoot: boolean;
expandStateRoot: boolean;
markStateDiff: boolean;
onActionClick: (id: number) => void;
onActionShiftClick: (id: number) => void;
}
export default class LogMonitorEntry<
S,
A extends Action<unknown>
> extends PureComponent<Props<S, A>> {
static propTypes = {
state: PropTypes.object.isRequired,
action: PropTypes.object.isRequired,
@ -36,15 +63,10 @@ export default class LogMonitorEntry extends PureComponent {
selected: PropTypes.bool,
expandActionRoot: PropTypes.bool,
expandStateRoot: PropTypes.bool,
previousState: PropTypes.object,
};
constructor(props) {
super(props);
this.handleActionClick = this.handleActionClick.bind(this);
this.shouldExpandNode = this.shouldExpandNode.bind(this);
}
printState(state, error) {
printState(state: S, error: string | undefined) {
let errorText = error;
if (!errorText) {
try {
@ -56,7 +78,11 @@ export default class LogMonitorEntry extends PureComponent {
typeof this.props.previousState !== 'undefined'
? this.props.select(this.props.previousState)
: undefined;
const getValueStyle = ({ style }, nodeType, keyPath) => ({
const getValueStyle: StylingValue = (
{ style },
nodeType,
keyPath
) => ({
style: {
...style,
backgroundColor: dataIsEqual(data, previousData, keyPath)
@ -64,7 +90,7 @@ export default class LogMonitorEntry extends PureComponent {
: this.props.theme.base01,
},
});
const getNestedNodeStyle = ({ style }, keyPath) => ({
const getNestedNodeStyle: StylingValue = ({ style }, keyPath) => ({
style: {
...style,
...(keyPath.length > 1 ? {} : styles.root),
@ -72,7 +98,6 @@ export default class LogMonitorEntry extends PureComponent {
});
theme = {
extend: this.props.theme,
tree: styles.tree,
value: getValueStyle,
nestedNode: getNestedNodeStyle,
};
@ -109,7 +134,7 @@ export default class LogMonitorEntry extends PureComponent {
);
}
handleActionClick(e) {
handleActionClick: MouseEventHandler<HTMLDivElement> = (e) => {
const { actionId, onActionClick, onActionShiftClick } = this.props;
if (actionId > 0) {
if (e.shiftKey) {
@ -118,11 +143,15 @@ export default class LogMonitorEntry extends PureComponent {
onActionClick(actionId);
}
}
}
};
shouldExpandNode(keyName, data, level) {
shouldExpandNode = (
keyPath: (string | number)[],
data: any,
level: number
) => {
return this.props.expandStateRoot && level === 0;
}
};
render() {
const {

View File

@ -1,5 +1,7 @@
import React, { Component } from 'react';
import React, { Component, CSSProperties, MouseEventHandler } from 'react';
import JSONTree from 'react-json-tree';
import { Base16Theme } from 'redux-devtools-themes';
import { Action } from 'redux';
const styles = {
actionBar: {
@ -14,13 +16,19 @@ const styles = {
},
};
export default class LogMonitorAction extends Component {
constructor(props) {
super(props);
this.shouldExpandNode = this.shouldExpandNode.bind(this);
}
interface Props<A extends Action<unknown>> {
theme: Base16Theme;
collapsed: boolean;
action: A;
expandActionRoot: boolean;
onClick: MouseEventHandler<HTMLDivElement>;
style: CSSProperties;
}
renderPayload(payload) {
export default class LogMonitorAction<
A extends Action<unknown>
> extends Component<Props<A>> {
renderPayload(payload: Record<string, unknown>) {
return (
<div
style={{
@ -43,9 +51,13 @@ export default class LogMonitorAction extends Component {
);
}
shouldExpandNode(keyName, data, level) {
shouldExpandNode = (
keyPath: (string | number)[],
data: any,
level: number
) => {
return this.props.expandActionRoot && level === 0;
}
};
render() {
const { type, ...payload } = this.props.action;
@ -58,7 +70,7 @@ export default class LogMonitorAction extends Component {
}}
>
<div style={styles.actionBar} onClick={this.props.onClick}>
{type !== null && type.toString()}
{type !== null && (type as string).toString()}
</div>
{!this.props.collapsed ? this.renderPayload(payload) : ''}
</div>

View File

@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Action } from 'redux';
import { PerformAction } from 'redux-devtools';
import { Base16Theme } from 'base16';
import { Base16Theme } from 'redux-devtools-themes';
import LogMonitorEntry from './LogMonitorEntry';
interface Props<S, A extends Action<unknown>> {

View File

@ -1,9 +1,9 @@
import { Action } from 'redux';
import {
UPDATE_SCROLL_TOP,
START_CONSECUTIVE_TOGGLE,
LogMonitorAction,
} from './actions';
import { Action } from 'redux';
import { LogMonitorProps } from './LogMonitor';
function initialScrollTop<S, A extends Action<unknown>>(