unageanu/jiji2

View on GitHub
sites/src/js/view/components/logs/log-viewer.js

Summary

Maintainability
A
1 hr
Test Coverage
import React             from "react"

import AbstractComponent from "../widgets/abstract-component"
import LoadingImage      from "../widgets/loading-image"
import Theme             from "../../theme"

import FlatButton from "material-ui/FlatButton"
import IconButton from "material-ui/IconButton"
import Card from "material-ui/Card"

const keys = new Set([
  "items", "pageSelectors", "loading"
]);

export default class LogViewer extends AbstractComponent {

  constructor(props) {
    super(props);
    this.state = {
      items : [],
      pageSelectors: [],
      loading: true
    };
  }

  componentWillMount() {
    this.registerPropertyChangeListener(this.props.model, keys);
    const state = this.collectInitialState(this.props.model, keys);
    this.setState(state);
  }

  render() {
    const menu = this.createMenu();
    const body = this.createBodyContnet();
    return (
      <div className="log-viewer">
        {menu}
        <div className="body">
          {body}
        </div>
      </div>
    );
  }

  createMenu() {
    if (!this.existLog()) return null;
    const pageSelectorElements = this.createPageSelectorElements();
    const scroller = this.createScrollerElements();
    return <Card className="menu">
      <span className="page-selector">{pageSelectorElements}</span>
      <span className="scroller">{scroller}</span>
    </Card>;
  }

  createBodyContnet() {
    if (!this.state.items || this.state.loading) {
      return <div className="center-information loading">
        <LoadingImage left={-20}/>
      </div>;
    } else if (!this.existLog()) {
      return <div className="center-information">
        ログはありません
      </div>;
    } else {
      return <pre>{this.state.items[0].body}</pre>;
    }
  }
  createScrollerElements() {
    const contentSize = this.context.windowResizeManager.contentSize;
    const windowSize  = this.context.windowResizeManager.windowSize;
    return [{
      icon:"expand-less",
      action: () => window.scrollTo(0, 0),
      tooltip: "一番上へ"
    }, {
      icon:"expand-more",
      action: () => window.scrollTo(0, contentSize.h - windowSize.h),
      tooltip: "一番下へ"
    }].map((info, index)=> {
      return <IconButton
          key={info.icon}
          className="scroller-button"
          tooltip={info.tooltip}
          tooltipPosition="top-center"
          iconClassName={"md-"+info.icon}
          onTouchTap={info.action}
        />;
    });
  }
  createPageSelectorElements() {
    return this.state.pageSelectors.map((selector, index)=> {
      return this.createPageSelectorElement(selector, index);
    });
  }

  createPageSelectorElement(selector, index) {
    if (selector.action) {
      const className = selector.selected ? "selected" : "";
      const palette = Theme.palette;
      return (
        <FlatButton
          className={"selector " + className}
          key={index}
          label={""+selector.label}
          onClick={selector.action}
          style={{
            minWidth: "36px",
            border: "1px solid " +
              (selector.selected ? palette.accent1Color : palette.borderColor),
            marginRight: "8px",
            borderRadius: "0px"
          }}
          labelStyle={{
            padding: "0px 8px",
            color: selector.selected ? palette.accent1Color : palette.textColor
          }}
        />
      );
    } else {
      return <span
        key={index}
        className="separator">
        {selector.label}
      </span>;
    }
  }

  existLog() {
    return this.state.items
        && this.state.items.length > 0
        && this.state.items[0].body;
  }

}
LogViewer.propTypes = {
  model: React.PropTypes.object
};
LogViewer.defaultProps = {
  model: null
};
LogViewer.contextTypes = {
  windowResizeManager: React.PropTypes.object.isRequired
};