mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-06 15:31:16 +08:00
77 lines
2.2 KiB
JavaScript
77 lines
2.2 KiB
JavaScript
/* eslint-disable no-underscore-dangle */
|
|
|
|
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import deepEqual from 'deep-equal';
|
|
import { CYCLIC_KEY, retrocycle } from '../../lib';
|
|
import { isObject } from '../../lib/util';
|
|
|
|
import ActionLoggerComponent from '../../components/ActionLogger/';
|
|
import { EVENT_ID } from '../../';
|
|
|
|
export default class ActionLogger extends React.Component {
|
|
constructor(props, ...args) {
|
|
super(props, ...args);
|
|
this.state = { actions: [] };
|
|
this._actionListener = action => this.addAction(action);
|
|
this._storyChangeListener = () => this.handleStoryChange();
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.props.channel.on(EVENT_ID, this._actionListener);
|
|
this.stopListeningOnStory = this.props.api.onStory(this._storyChangeListener);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.props.channel.removeListener(EVENT_ID, this._actionListener);
|
|
if (this.stopListeningOnStory) {
|
|
this.stopListeningOnStory();
|
|
}
|
|
}
|
|
|
|
handleStoryChange() {
|
|
const { actions } = this.state;
|
|
if (actions.length > 0 && actions[0].options.clearOnStoryChange) {
|
|
this.clearActions();
|
|
}
|
|
}
|
|
|
|
addAction(action) {
|
|
action.data.args = action.data.args.map(arg => retrocycle(arg)); // eslint-disable-line
|
|
const isCyclic = !!action.data.args.find(arg => isObject(arg) && arg[CYCLIC_KEY]);
|
|
const actions = [...this.state.actions];
|
|
const previous = actions.length && actions[0];
|
|
|
|
if (previous && !isCyclic && deepEqual(previous.data, action.data, { strict: true })) {
|
|
previous.count++; // eslint-disable-line
|
|
} else {
|
|
action.count = 1; // eslint-disable-line
|
|
actions.unshift(action);
|
|
}
|
|
this.setState({ actions: actions.slice(0, action.options.limit) });
|
|
}
|
|
|
|
clearActions() {
|
|
this.setState({ actions: [] });
|
|
}
|
|
|
|
render() {
|
|
const props = {
|
|
actions: this.state.actions,
|
|
onClear: () => this.clearActions(),
|
|
};
|
|
return <ActionLoggerComponent {...props} />;
|
|
}
|
|
}
|
|
|
|
ActionLogger.propTypes = {
|
|
// eslint-disable-next-line react/forbid-prop-types
|
|
channel: PropTypes.object,
|
|
api: PropTypes.shape({
|
|
onStory: PropTypes.func.isRequired,
|
|
}).isRequired,
|
|
};
|
|
ActionLogger.defaultProps = {
|
|
channel: {},
|
|
};
|