Skip to content

feature(redux-devtools-inspector-monitor): sorted state tree #1264

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

Merged
merged 1 commit into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions .changeset/plenty-gifts-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'remotedev-redux-devtools-extension': minor
'@redux-devtools/inspector-monitor': minor
---

Option to sort State Tree keys alphabetically
Option to disable collapsing of object keys
3 changes: 3 additions & 0 deletions extension/src/app/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Actions extends Component<Props> {
liftedState,
liftedDispatch,
position,
stateTreeSettings,
} = this.props;
const { features } = options;
return (
Expand All @@ -75,6 +76,7 @@ class Actions extends Component<Props> {
monitorState={this.props.monitorState}
dispatch={liftedDispatch}
features={options.features}
stateTreeSettings={stateTreeSettings}
/>
{sliderIsOpen && options.connectionId && options.features.jump && (
<SliderMonitor liftedState={liftedState} dispatch={liftedDispatch} />
Expand Down Expand Up @@ -149,6 +151,7 @@ const mapStateToProps = (state: StoreState) => {
dispatcherIsOpen: state.monitor.dispatcherIsOpen,
sliderIsOpen: state.monitor.sliderIsOpen,
reports: state.reports.data,
stateTreeSettings: state.stateTreeSettings,
};
};

Expand Down
2 changes: 2 additions & 0 deletions extension/src/window/store/windowReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
section,
socket,
theme,
stateTreeSettings,
StoreState,
} from '@redux-devtools/app';
import instances from './instancesReducer';
Expand All @@ -22,6 +23,7 @@ const rootReducer: Reducer<StoreState, WindowStoreAction> =
section,
theme,
connection,
stateTreeSettings,
});

export default rootReducer;
23 changes: 23 additions & 0 deletions packages/redux-devtools-app/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
GET_REPORT_SUCCESS,
ERROR,
SET_PERSIST,
CHANGE_STATE_TREE_SETTINGS,
} from '../constants/actionTypes';
import {
AUTH_ERROR,
Expand Down Expand Up @@ -82,6 +83,27 @@ export function changeTheme(data: ChangeThemeData): ChangeThemeAction {
return { type: CHANGE_THEME, ...data.formData };
}

interface ChangeStateTreeSettingsFormData {
readonly sortAlphabetically: boolean;
readonly disableCollection: boolean;
}

interface ChangeStateTreeSettingsData {
readonly formData: ChangeStateTreeSettingsFormData;
}

export interface ChangeStateTreeSettingsAction {
readonly type: typeof CHANGE_STATE_TREE_SETTINGS;
readonly sortAlphabetically: boolean;
readonly disableCollection: boolean;
}

export function changeStateTreeSettings(
data: ChangeStateTreeSettingsData
): ChangeStateTreeSettingsAction {
return { type: CHANGE_STATE_TREE_SETTINGS, ...data.formData };
}

export interface InitMonitorAction {
type: '@@INIT_MONITOR';
newMonitorState: unknown;
Expand Down Expand Up @@ -568,6 +590,7 @@ interface ReduxPersistRehydrateAction {
export type StoreActionWithoutUpdateStateOrLiftedAction =
| ChangeSectionAction
| ChangeThemeAction
| ChangeStateTreeSettingsAction
| MonitorActionAction
| SelectInstanceAction
| SelectMonitorAction
Expand Down
52 changes: 52 additions & 0 deletions packages/redux-devtools-app/src/components/Settings/StateTree.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { Component } from 'react';
import { connect, ResolveThunks } from 'react-redux';
import { Container, Form } from '@redux-devtools/ui';
import { changeStateTreeSettings } from '../../actions';
import { StoreState } from '../../reducers';

type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps;

export class StateTree extends Component<Props> {
render() {
const stateTree = this.props.theme;
const formData = {
sortAlphabetically: stateTree.sortAlphabetically,
disableCollection: stateTree.disableCollection,
};

return (
<Container>
<Form
schema={{
type: 'object',
properties: {
sortAlphabetically: {
title: 'Sort Alphabetically',
type: 'boolean',
},
disableCollection: {
title: 'Disable collapsing of nodes',
type: 'boolean',
},
},
}}
formData={formData}
noSubmit
onChange={this.props.changeStateTreeSettings}
/>
</Container>
);
}
}

const mapStateToProps = (state: StoreState) => ({
theme: state.stateTreeSettings,
});

const actionCreators = {
changeStateTreeSettings,
};

export default connect(mapStateToProps, actionCreators)(StateTree);
2 changes: 2 additions & 0 deletions packages/redux-devtools-app/src/components/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { Tabs } from '@redux-devtools/ui';
import Connection from './Connection';
import Themes from './Themes';
import StateTree from './StateTree';

interface State {
selected: string;
Expand All @@ -12,6 +13,7 @@ export default class Settings extends Component<{}, State> {
tabs = [
{ name: 'Connection', component: Connection },
{ name: 'Themes', component: Themes },
{ name: 'State Tree', component: StateTree },
];
state: State = { selected: 'Connection' };

Expand Down
1 change: 1 addition & 0 deletions packages/redux-devtools-app/src/constants/actionTypes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const CHANGE_SECTION = 'main/CHANGE_SECTION';
export const CHANGE_THEME = 'main/CHANGE_THEME';
export const CHANGE_STATE_TREE_SETTINGS = 'main/CHANGE_STATE_TREE_SETTINGS';

export const UPDATE_STATE = 'devTools/UPDATE_STATE';
export const SET_STATE = 'devTools/SET_STATE';
Expand Down
3 changes: 3 additions & 0 deletions packages/redux-devtools-app/src/containers/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Actions extends Component<Props> {
options,
liftedState,
liftedDispatch,
stateTreeSettings,
} = this.props;
return (
<Container>
Expand All @@ -37,6 +38,7 @@ class Actions extends Component<Props> {
monitorState={this.props.monitorState}
dispatch={liftedDispatch}
features={options.features}
stateTreeSettings={stateTreeSettings}
/>
{sliderIsOpen && options.connectionId && options.features.jump && (
<SliderMonitor liftedState={liftedState} dispatch={liftedDispatch} />
Expand Down Expand Up @@ -65,6 +67,7 @@ const mapStateToProps = (state: StoreState) => {
dispatcherIsOpen: state.monitor.dispatcherIsOpen,
sliderIsOpen: state.monitor.sliderIsOpen,
reports: state.reports.data,
stateTreeSettings: state.stateTreeSettings,
};
};

Expand Down
8 changes: 8 additions & 0 deletions packages/redux-devtools-app/src/containers/DevTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { InitMonitorAction } from '../actions';
import { Features, State } from '../reducers/instances';
import { MonitorStateMonitorState } from '../reducers/monitor';
import { ThemeFromProvider } from '@redux-devtools/ui';
import { StateTreeSettings } from '../reducers/stateTreeSettings';

interface Props {
monitor: string;
Expand All @@ -17,6 +18,7 @@ interface Props {
) => void;
features: Features | undefined;
theme: ThemeFromProvider;
stateTreeSettings: StateTreeSettings;
}

class DevTools extends Component<Props> {
Expand Down Expand Up @@ -110,6 +112,12 @@ class DevTools extends Component<Props> {
features={this.props.features}
dispatch={this.dispatch}
theme={this.props.theme}
sortStateTreeAlphabetically={
this.props.stateTreeSettings.sortAlphabetically
}
disableStateTreeCollection={
this.props.stateTreeSettings.disableCollection
}
/>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions packages/redux-devtools-app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ export * from './reducers/reports';
export * from './reducers/section';
export * from './reducers/socket';
export * from './reducers/theme';
export * from './reducers/stateTreeSettings';
export * from './utils/monitorActions';
export * from './utils/stringifyJSON';
3 changes: 3 additions & 0 deletions packages/redux-devtools-app/src/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import { instances, InstancesState } from './instances';
import { reports, ReportsState } from './reports';
import { theme, ThemeState } from './theme';
import { StoreAction } from '../actions';
import { stateTreeSettings, StateTreeSettings } from './stateTreeSettings';

export interface StoreState {
readonly section: SectionState;
readonly theme: ThemeState;
readonly stateTreeSettings: StateTreeSettings;
readonly connection: ConnectionState;
readonly socket: SocketState;
readonly monitor: MonitorState;
Expand All @@ -23,6 +25,7 @@ export interface StoreState {
export const rootReducer = combineReducers<StoreState, StoreAction>({
section,
theme,
stateTreeSettings,
connection,
socket,
monitor,
Expand Down
23 changes: 23 additions & 0 deletions packages/redux-devtools-app/src/reducers/stateTreeSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { CHANGE_STATE_TREE_SETTINGS } from '../constants/actionTypes';
import { StoreAction } from '../actions';

export interface StateTreeSettings {
readonly sortAlphabetically: boolean;
readonly disableCollection: boolean;
}

export function stateTreeSettings(
state: StateTreeSettings = {
sortAlphabetically: false,
disableCollection: false,
},
action: StoreAction
) {
if (action.type === CHANGE_STATE_TREE_SETTINGS) {
return {
sortAlphabetically: action.sortAlphabetically,
disableCollection: action.disableCollection,
};
}
return state;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export interface TabComponentProps<S, A extends Action<unknown>> {
base16Theme: Base16Theme;
invertTheme: boolean;
isWideLayout: boolean;
sortStateTreeAlphabetically: boolean;
disableStateTreeCollection: boolean;
dataTypeKey: string | symbol | undefined;
delta: Delta | null | undefined | false;
action: A;
Expand Down Expand Up @@ -70,6 +72,8 @@ interface Props<S, A extends Action<unknown>> {
onInspectPath: (path: (string | number)[]) => void;
inspectedPath: (string | number)[];
onSelectTab: (tabName: string) => void;
sortStateTreeAlphabetically: boolean;
disableStateTreeCollection: boolean;
}

class ActionPreview<S, A extends Action<unknown>> extends Component<
Expand Down Expand Up @@ -101,6 +105,8 @@ class ActionPreview<S, A extends Action<unknown>> extends Component<
dataTypeKey,
monitorState,
updateMonitorState,
sortStateTreeAlphabetically,
disableStateTreeCollection,
} = this.props;

const renderedTabs: Tab<S, A>[] =
Expand Down Expand Up @@ -133,6 +139,8 @@ class ActionPreview<S, A extends Action<unknown>> extends Component<
base16Theme,
invertTheme,
isWideLayout,
sortStateTreeAlphabetically,
disableStateTreeCollection,
dataTypeKey,
delta,
action,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ export interface ExternalProps<S, A extends Action<unknown>> {
hideMainButtons?: boolean;
hideActionButtons?: boolean;
invertTheme: boolean;
sortStateTreeAlphabetically: boolean;
disableStateTreeCollection: boolean;
dataTypeKey?: string | symbol;
tabs: Tab<S, A>[] | ((tabs: Tab<S, A>[]) => Tab<S, A>[]);
}
Expand All @@ -177,6 +179,8 @@ export interface DevtoolsInspectorProps<S, A extends Action<unknown>>
diffPropertyFilter?: (name: string, context: DiffContext) => boolean;
hideMainButtons?: boolean;
hideActionButtons?: boolean;
sortStateTreeAlphabetically: boolean;
disableStateTreeCollection: boolean;
invertTheme: boolean;
dataTypeKey?: string | symbol;
tabs: Tab<S, A>[] | ((tabs: Tab<S, A>[]) => Tab<S, A>[]);
Expand Down Expand Up @@ -220,6 +224,8 @@ class DevtoolsInspector<S, A extends Action<unknown>> extends PureComponent<
hideMainButtons: PropTypes.bool,
hideActionButtons: PropTypes.bool,
invertTheme: PropTypes.bool,
sortStateTreeAlphabetically: PropTypes.bool,
disableStateTreeCollection: PropTypes.bool,
skippedActionIds: PropTypes.array,
dataTypeKey: PropTypes.any,
tabs: PropTypes.oneOfType([PropTypes.array, PropTypes.func]),
Expand Down Expand Up @@ -305,6 +311,8 @@ class DevtoolsInspector<S, A extends Action<unknown>> extends PureComponent<
dataTypeKey,
hideMainButtons,
hideActionButtons,
sortStateTreeAlphabetically,
disableStateTreeCollection,
} = this.props;
const { selectedActionId, startActionId, searchValue, tabName } =
monitorState;
Expand Down Expand Up @@ -364,6 +372,8 @@ class DevtoolsInspector<S, A extends Action<unknown>> extends PureComponent<
selectedActionId,
startActionId,
dataTypeKey,
sortStateTreeAlphabetically,
disableStateTreeCollection,
}}
monitorState={this.props.monitorState}
updateMonitorState={this.updateMonitorState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const StateTab: React.FunctionComponent<
labelRenderer,
dataTypeKey,
isWideLayout,
sortStateTreeAlphabetically,
disableStateTreeCollection,
}) => (
<JSONTree
labelRenderer={labelRenderer}
Expand All @@ -26,6 +28,8 @@ const StateTab: React.FunctionComponent<
}
invertTheme={invertTheme}
hideRoot
sortObjectKeys={sortStateTreeAlphabetically}
{...(disableStateTreeCollection ? { collectionLimit: 0 } : {})}
/>
);

Expand Down