import React from "react" import ReactDOM from "react-dom" import shallowEqual from "shallowequal" import {Query} from "../actions.js" import AutoScroll from "./helpers/AutoScroll"; import {calcVScroll} from "./helpers/VirtualScroll" import {StoreView} from "../store/view.js" import _ from "lodash" class EventLogContents extends React.Component { static contextTypes = { eventStore: React.PropTypes.object.isRequired, }; static defaultProps = { rowHeight: 18, }; constructor(props, context) { super(props, context); this.view = new StoreView( this.context.eventStore, entry => this.props.filter[entry.level] ); this.heights = {}; this.state = { entries: this.view.list, vScroll: calcVScroll() }; this.onChange = this.onChange.bind(this); this.onViewportUpdate = this.onViewportUpdate.bind(this); } componentDidMount() { window.addEventListener("resize", this.onViewportUpdate); this.view.addListener("add", this.onChange); this.view.addListener("recalculate", this.onChange); this.onViewportUpdate(); } componentWillUnmount() { window.removeEventListener("resize", this.onViewportUpdate); this.view.removeListener("add", this.onChange); this.view.removeListener("recalculate", this.onChange); this.view.close(); } componentDidUpdate() { this.onViewportUpdate(); } componentWillReceiveProps(nextProps) { if (nextProps.filter !== this.props.filter) { this.view.recalculate( entry => nextProps.filter[entry.level] ); } } onViewportUpdate() { const viewport = ReactDOM.findDOMNode(this); const vScroll = calcVScroll({ itemCount: this.state.entries.length, rowHeight: this.props.rowHeight, viewportTop: viewport.scrollTop, viewportHeight: viewport.offsetHeight, itemHeights: this.state.entries.map(entry => this.heights[entry.id]), }); if (!shallowEqual(this.state.vScroll, vScroll)) { this.setState({ vScroll }); } } onChange() { this.setState({ entries: this.view.list }); } setHeight(id, ref) { if (ref && !this.heights[id]) { const height = ReactDOM.findDOMNode(ref).offsetHeight; if (this.heights[id] !== height) { this.heights[id] = height; this.onViewportUpdate(); } } } getIcon(level) { return { web: "html5", debug: "bug" }[level] || "info"; } render() { const vScroll = this.state.vScroll; const entries = this.state.entries.slice(vScroll.start, vScroll.end); return (
{entries.map((entry, index) => (
{entry.message}
))}
);
}
}
ToggleFilter.propTypes = {
name: React.PropTypes.string.isRequired,
toggleLevel: React.PropTypes.func.isRequired,
active: React.PropTypes.bool,
};
function ToggleFilter ({ name, active, toggleLevel }) {
let className = "label ";
if (active) {
className += "label-primary";
} else {
className += "label-default";
}
function onClick(event) {
event.preventDefault();
toggleLevel(name);
}
return (
{name}
);
}
const AutoScrollEventLog = AutoScroll(EventLogContents);
var EventLog = React.createClass({
getInitialState() {
return {
filter: {
"debug": false,
"info": true,
"web": true
}
};
},
close() {
var d = {};
d[Query.SHOW_EVENTLOG] = undefined;
this.props.updateLocation(undefined, d);
},
toggleLevel(level) {
var filter = _.extend({}, this.state.filter);
filter[level] = !filter[level];
this.setState({filter: filter});
},
render() {
return (