[web] eventlog.js -> EventLog.jsx
This commit is contained in:
parent
1baefcdc99
commit
6c95635cb8
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,41 @@
|
|||
import React, { PropTypes } from 'react'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
import { toggleEventLogFilter, toggleEventLogVisibility } from '../ducks/eventLog'
|
||||
import { ToggleButton } from './common'
|
||||
import EventList from './EventLog/EventList'
|
||||
|
||||
EventLog.propTypes = {
|
||||
filters: PropTypes.object.isRequired,
|
||||
events: PropTypes.array.isRequired,
|
||||
onToggleFilter: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
function EventLog({ filters, events, onToggleFilter, onClose }) {
|
||||
return (
|
||||
<div className="eventlog">
|
||||
<div>
|
||||
Eventlog
|
||||
<div className="pull-right">
|
||||
{['debug', 'info', 'web'].map(type => (
|
||||
<ToggleButton text={type} checked={filters[type]} onToggle={() => onToggleFilter(type)}/>
|
||||
))}
|
||||
<i onClick={onClose} className="fa fa-close"></i>
|
||||
</div>
|
||||
</div>
|
||||
<EventList events={events} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default connect(
|
||||
state => ({
|
||||
filters: state.eventLog.filter,
|
||||
events: state.eventLog.filteredEvents,
|
||||
}),
|
||||
dispatch => bindActionCreators({
|
||||
onClose: toggleEventLogVisibility,
|
||||
onToggleFilter: toggleEventLogFilter,
|
||||
}, dispatch)
|
||||
)(EventLog)
|
|
@ -0,0 +1,90 @@
|
|||
import React, { Component, PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import shallowEqual from 'shallowequal'
|
||||
import AutoScroll from '../helpers/AutoScroll'
|
||||
import { calcVScroll } from '../helpers/VirtualScroll'
|
||||
|
||||
class EventLogList extends Component {
|
||||
|
||||
static propTypes = {
|
||||
events: PropTypes.array.isRequired,
|
||||
rowHeight: PropTypes.number,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
rowHeight: 18,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.heights = {}
|
||||
this.state = { vScroll: calcVScroll() }
|
||||
|
||||
this.onViewportUpdate = this.onViewportUpdate.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.onViewportUpdate)
|
||||
this.onViewportUpdate()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.onViewportUpdate)
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.onViewportUpdate()
|
||||
}
|
||||
|
||||
onViewportUpdate() {
|
||||
const viewport = ReactDOM.findDOMNode(this)
|
||||
|
||||
const vScroll = calcVScroll({
|
||||
itemCount: this.props.events.length,
|
||||
rowHeight: this.props.rowHeight,
|
||||
viewportTop: viewport.scrollTop,
|
||||
viewportHeight: viewport.offsetHeight,
|
||||
itemHeights: this.props.events.map(entry => this.heights[entry.id]),
|
||||
})
|
||||
|
||||
if (!shallowEqual(this.state.vScroll, vScroll)) {
|
||||
this.setState({vScroll})
|
||||
}
|
||||
}
|
||||
|
||||
setHeight(id, node) {
|
||||
if (node && !this.heights[id]) {
|
||||
const height = node.offsetHeight
|
||||
if (this.heights[id] !== height) {
|
||||
this.heights[id] = height
|
||||
this.onViewportUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { vScroll } = this.state
|
||||
const { events } = this.props
|
||||
|
||||
return (
|
||||
<pre onScroll={this.onViewportUpdate}>
|
||||
<div style={{ height: vScroll.paddingTop }}></div>
|
||||
{events.slice(vScroll.start, vScroll.end).map(event => (
|
||||
<div key={event.id} ref={node => this.setHeight(event.id, node)}>
|
||||
<LogIcon event={event}/>
|
||||
{event.message}
|
||||
</div>
|
||||
))}
|
||||
<div style={{ height: vScroll.paddingBottom }}></div>
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function LogIcon({ event }) {
|
||||
const icon = { web: 'html5', debug: 'bug' }[event.level] || 'info'
|
||||
return <i className={`fa fa-fw fa-${icon}`}></i>
|
||||
}
|
||||
|
||||
export default AutoScroll(EventLogList)
|
|
@ -5,7 +5,7 @@ import { connect } from 'react-redux'
|
|||
|
||||
import { Splitter } from "./common.js"
|
||||
import { Header, MainMenu } from "./header.js"
|
||||
import EventLog from "./eventlog.js"
|
||||
import EventLog from "./EventLog"
|
||||
import Footer from "./Footer"
|
||||
import { SettingsStore } from "../store/store.js"
|
||||
import { Key } from "../utils.js"
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
import React from "react"
|
||||
import ReactDOM from "react-dom"
|
||||
import {connect} from 'react-redux'
|
||||
import shallowEqual from "shallowequal"
|
||||
import {toggleEventLogFilter, toggleEventLogVisibility} from "../ducks/eventLog"
|
||||
import AutoScroll from "./helpers/AutoScroll";
|
||||
import {calcVScroll} from "./helpers/VirtualScroll"
|
||||
import {ToggleButton} from "./common";
|
||||
|
||||
function LogIcon({event}) {
|
||||
let icon = {web: "html5", debug: "bug"}[event.level] || "info";
|
||||
return <i className={`fa fa-fw fa-${icon}`}></i>
|
||||
}
|
||||
|
||||
function LogEntry({event, registerHeight}) {
|
||||
return <div ref={registerHeight}>
|
||||
<LogIcon event={event}/>
|
||||
{event.message}
|
||||
</div>;
|
||||
}
|
||||
|
||||
class EventLogContents extends React.Component {
|
||||
|
||||
static defaultProps = {
|
||||
rowHeight: 18,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.heights = {};
|
||||
this.state = {vScroll: calcVScroll()};
|
||||
|
||||
this.onViewportUpdate = this.onViewportUpdate.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.onViewportUpdate);
|
||||
this.onViewportUpdate();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.onViewportUpdate);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.onViewportUpdate();
|
||||
}
|
||||
|
||||
onViewportUpdate() {
|
||||
const viewport = ReactDOM.findDOMNode(this);
|
||||
|
||||
const vScroll = calcVScroll({
|
||||
itemCount: this.props.events.length,
|
||||
rowHeight: this.props.rowHeight,
|
||||
viewportTop: viewport.scrollTop,
|
||||
viewportHeight: viewport.offsetHeight,
|
||||
itemHeights: this.props.events.map(entry => this.heights[entry.id]),
|
||||
});
|
||||
|
||||
if (!shallowEqual(this.state.vScroll, vScroll)) {
|
||||
this.setState({vScroll});
|
||||
}
|
||||
}
|
||||
|
||||
setHeight(id, node) {
|
||||
if (node && !this.heights[id]) {
|
||||
const height = node.offsetHeight;
|
||||
if (this.heights[id] !== height) {
|
||||
this.heights[id] = height;
|
||||
this.onViewportUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const vScroll = this.state.vScroll;
|
||||
const events = this.props.events
|
||||
.slice(vScroll.start, vScroll.end)
|
||||
.map(event =>
|
||||
<LogEntry
|
||||
event={event}
|
||||
key={event.id}
|
||||
registerHeight={(node) => this.setHeight(event.id, node)}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<pre onScroll={this.onViewportUpdate}>
|
||||
<div style={{ height: vScroll.paddingTop }}></div>
|
||||
{events}
|
||||
<div style={{ height: vScroll.paddingBottom }}></div>
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EventLogContents = AutoScroll(EventLogContents);
|
||||
|
||||
|
||||
const EventLogContentsContainer = connect(
|
||||
state => ({
|
||||
events: state.eventLog.filteredEvents
|
||||
})
|
||||
)(EventLogContents);
|
||||
|
||||
|
||||
export const ToggleEventLog = connect(
|
||||
state => ({
|
||||
checked: state.eventLog.visible
|
||||
}),
|
||||
dispatch => ({
|
||||
onToggle: () => dispatch(toggleEventLogVisibility())
|
||||
})
|
||||
)(ToggleButton);
|
||||
|
||||
|
||||
const ToggleFilter = connect(
|
||||
(state, ownProps) => ({
|
||||
checked: state.eventLog.filter[ownProps.text]
|
||||
}),
|
||||
(dispatch, ownProps) => ({
|
||||
onToggle: () => dispatch(toggleEventLogFilter(ownProps.text))
|
||||
})
|
||||
)(ToggleButton);
|
||||
|
||||
|
||||
const EventLog = ({close}) =>
|
||||
<div className="eventlog">
|
||||
<div>
|
||||
Eventlog
|
||||
<div className="pull-right">
|
||||
<ToggleFilter text="debug"/>
|
||||
<ToggleFilter text="info"/>
|
||||
<ToggleFilter text="web"/>
|
||||
<i onClick={close} className="fa fa-close"></i>
|
||||
</div>
|
||||
</div>
|
||||
<EventLogContentsContainer/>
|
||||
</div>;
|
||||
|
||||
EventLog.propTypes = {
|
||||
close: React.PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const EventLogContainer = connect(
|
||||
undefined,
|
||||
dispatch => ({
|
||||
close: () => dispatch(toggleEventLogVisibility())
|
||||
})
|
||||
)(EventLog);
|
||||
|
||||
export default EventLogContainer;
|
|
@ -1,5 +1,6 @@
|
|||
import React from "react";
|
||||
import ReactDOM from 'react-dom';
|
||||
import { bindActionCreators } from 'redux'
|
||||
import $ from "jquery";
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
|
@ -9,7 +10,16 @@ import {ToggleInputButton, ToggleButton} from "./common.js";
|
|||
import {SettingsActions, FlowActions} from "../actions.js";
|
||||
import {Query} from "../actions.js";
|
||||
import {SettingsState} from "./common.js";
|
||||
import {ToggleEventLog} from "./eventlog"
|
||||
import { toggleEventLogVisibility } from '../ducks/eventLog'
|
||||
|
||||
const ToggleEventLog = connect(
|
||||
state => ({
|
||||
checked: state.eventLog.visible
|
||||
}),
|
||||
dispatch => bindActionCreators({
|
||||
onToggle: toggleEventLogVisibility,
|
||||
}, dispatch)
|
||||
)(ToggleButton)
|
||||
|
||||
var FilterDocs = React.createClass({
|
||||
statics: {
|
||||
|
|
Loading…
Reference in New Issue