<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Plato - components/Event/EventList.js</title>

  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="">
  <meta name="author" content="">

  <!--[if lt IE 9]>
  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->

  <link href="../../assets/css/vendor/morris.css" rel="stylesheet" type="text/css">
  <link href="../../assets/css/vendor/bootstrap.css" rel="stylesheet" type="text/css">
  <link href="../../assets/css/vendor/font-awesome.css" rel="stylesheet" type="text/css">
  <link href="../../assets/css/vendor/codemirror.css" rel="stylesheet" type="text/css">
  <link href="../../assets/css/plato.css" rel="stylesheet" type="text/css">
  <link href="../../assets/css/plato-file.css" rel="stylesheet" type="text/css">

</head>

<body>

<div class="navbar navbar-fixed-top">
  <div class="container">
    <a class="navbar-brand" href="https://github.com/the-simian/es6-plato">ES6 Plato on Github</a>
    <ul class="nav navbar-nav">
      <li>
        <a href="../../index.html">Report Home</a>
      </li>
      <li class="active">
        <a href="display.html">Summary Display</a>
      </li>
    </ul>
  </div>
</div>

<div class="jumbotron">
  <div class="container">
    <h1>components/Event/EventList.js</h1>
  </div>
</div>

<div class="container aggregate-stats">
  <div class="row">
    <div class="col-md-6">
      <h2 class="header">Maintainability <a href="http://blogs.msdn.com/b/codeanalysis/archive/2007/11/20/maintainability-index-range-and-meaning.aspx"><i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="A value between 0 and 100 that represents the relative ease of maintaining the code. A high value means better maintainability." data-original-title="Maintainability Index"  data-container="body"></i></a></h2>
      <p class="stat">69.07</p>
    </div>
    <div class="col-md-6">
      <h2 class="header">Lines of code <i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="Source Lines of Code / Logical Lines of Code" data-original-title="SLOC/LSLOC" data-container="body"></i></h2>
      <p class="stat">195</p>
    </div>
  </div>
  <div class="row historical">
    <div class="col-md-6">
      <p id="chart_historical_maint" class="chart"></p>
    </div>
    <div class="col-md-6">
      <p id="chart_historical_sloc" class="chart"></p>
    </div>
  </div>
  <div class="row">
    <div class="col-md-6">
      <h2 class="header">Difficulty  <a href="http://en.wikipedia.org/wiki/Halstead_complexity_measures"><i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="The difficulty measure is related to the difficulty of the program to write or understand." data-original-title="Difficulty" data-container="body"></i></a></h2>
      <p class="stat">30.03</p>
    </div>
    <div class="col-md-6">
      <h2 class="header">Estimated Errors  <a href="http://en.wikipedia.org/wiki/Halstead_complexity_measures"><i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="Halstead's delivered bugs is an estimate for the number of errors in the implementation." data-original-title="Delivered Bugs" data-container="body"></i></a></h2>
      <p class="stat">1.20</p>
    </div>
  </div>
</div>

<div class="container charts">
  <div class="row">
    <h2 class="header">Function weight</h2>
  </div>
  <div class="row">
    <div class="col-md-6">
      <h3 class="chart-header">By Complexity <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity"><i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="This metric counts the number of distinct paths through a block of code. Lower values are better." data-original-title="Cyclomatic Complexity" data-container="body"></i></a></h3>
      <div id="fn-by-complexity" class="stat"></div>
    </div>
    <div class="col-md-6">
      <h3 class="chart-header">By SLOC  <i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="Source Lines of Code / Logical Lines of Code" data-original-title="SLOC/LSLOC" data-container="body"></i></h3>
      <div id="fn-by-sloc" class="stat"></div>
    </div>
  </div>
</div>

<div class="container">
  <div class="row">
    <textarea id="file-source" class="col-md-12">import { DOC_VIEW } from &#039;../../constants/EventTypes&#039;;

import React from &#039;react&#039;
import ReactDOM from &#039;react-dom&#039;
import { Grid, Row, OverlayTrigger, Tooltip } from &#039;react-bootstrap&#039;
import PropTypes from &#039;prop-types&#039;
import _ from &#039;lodash&#039;
import Moment from &#039;moment&#039;

import { getOriginalEvent } from &#039;../../helpers/EventHelpers&#039;
import Event from &#039;./Event&#039;;
import UserMessage from &#039;../UserMessage&#039;;
import { INFO_MESSAGE_TYPE } from &#039;../../constants/UserMessages&#039;;

require(&quot;./event.css&quot;);

const VERTICAL_BAR_EXTRA_LENGTH_ON_TOP = 10;
const VERTICAL_BAR_EXTRA_LENGTH_ON_BOTTOM = 15;
const VERTICAL_BAR_LENGTH_UNIT = &#039;px&#039;;

/**
 * The list of the all events
 */
class EventList extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            verticalBarLength: &#039;0px&#039;,
            events: this.props.events, // the displayed (ie filtered) event list. The original list is in this.props.eventList
        }

        this.adjustVerticalBarLength = this.adjustVerticalBarLength.bind(this);
        // this.onEventUpdated = this.onEventUpdated.bind(this);
    }

    /** 
     * Executed after all the events have been properly displayed 
     */
    componentDidMount() {
        this.adjustVerticalBarLength();
    }

    componentDidUpdate() {
        this.adjustVerticalBarLength();
    }

    render() {
        const {
            events,
            investigationId,
            onEventUpdated,
            reverseEventsSortingByCreationDate,
            selectedEventId,
            user,
            updateEvent,
            view,
        } = this.props;

        /**
         * Get existing events grouped by date
         * 
         */
        function getGroupedEvents() {
            //Groups events by day. For each group (=each day), events are still sorted from the youngest to the oldest
            //groupedSortedEvents is an object : { &quot;Aug 3&quot;:{ [{json event1}, {json event2}] }, &quot;Aug 1&quot;:{ [{json event3}] } }
            let groupedSortedEvents = _.groupBy(events, function (o) {
                return Moment(getOriginalEvent(o).creationDate).format(&quot;MMMM D, YYYY&quot;);
            });

            // Iterates over each of the properties of the groupedSortedEvents object and create an array containing React components
            let eventsAndDates = [];
            let dateKey = 0;
            for (var propertyName in groupedSortedEvents) {
                eventsAndDates.push(
                    &lt;div key={dateKey}&gt;
                        &lt;TimeAxisMarks userView={view} value={propertyName} /&gt;
                        {groupedSortedEvents[propertyName].map(
                            (event, eventKey) =&gt; {
                                return (&lt;div key={eventKey}&gt;
                                    &lt;Event
                                        event={event}
                                        investigationId={investigationId}
                                        isSelected={event._id &amp;&amp; event._id === selectedEventId}
                                        onEventUpdated={onEventUpdated}
                                        reverseEventsSortingByCreationDate={reverseEventsSortingByCreationDate}
                                        user={user}
                                        updateEvent={updateEvent}
                                        view={view}
                                    /&gt;
                                &lt;/div&gt;)
                            }
                        )}
                    &lt;/div&gt;
                )
                dateKey += 1;
            }
            return eventsAndDates;
        }

        let verticalBarLengthOntop = VERTICAL_BAR_EXTRA_LENGTH_ON_TOP + VERTICAL_BAR_LENGTH_UNIT;

        if (!events || events.length === 0) {
            return (
                &lt;Grid fluid={true} ref={(element) =&gt; { this.grid = element }} &gt;
                    &lt;Row style={{ marginLeft: &#039;30px&#039;, marginRight: &#039;30px&#039;, marginTop: &#039;20px&#039; }}&gt;
                        &lt;UserMessage
                            message=&quot;The logbook is currently empty.&quot;
                            isTextCentered={true}
                            type={INFO_MESSAGE_TYPE}
                        /&gt;
                    &lt;/Row&gt;
                &lt;/Grid &gt;
            )
        }

        return (
            &lt;Grid fluid={true} ref={(element) =&gt; { this.grid = element }} &gt;
                &lt;Row style={{ height: verticalBarLengthOntop }}&gt;
                    &lt;div ref={(element) =&gt; this.verticalBar = element}
                        style={{
                            /* this is the vertical line */
                            content: &#039;&#039;,
                            position: &#039;relative&#039;,
                            height: this.state.verticalBarLength,
                            width: &#039;2px&#039;,
                            background: &#039;#CCCCCC&#039;,
                            zIndex: &#039;1&#039;,
                            marginLeft: &#039;120px&#039;,
                        }} /&gt;
                &lt;/Row&gt;
                {getGroupedEvents()}
            &lt;/Grid &gt;
        )
    }

    /**
     * Determine the grid height and deduce the vertical bar height.
     */
    adjustVerticalBarLength() {
        var node = ReactDOM.findDOMNode(this.grid);
        if (node) {
            let gridLength = node.clientHeight;
            let barLengthValue = gridLength + VERTICAL_BAR_EXTRA_LENGTH_ON_BOTTOM;
            let barLength = barLengthValue + VERTICAL_BAR_LENGTH_UNIT;
            if (barLength !== this.state.verticalBarLength) {
                this.setState({ verticalBarLength: barLength });
            }
        }
    }



}

const TimeAxisMarks = (props) =&gt; {
    let userView = props.userView; // the view the user has choosen &#039;doc&#039; or &#039;monitoring&#039;

    if (userView === DOC_VIEW) {
        /* to be removed */
        return (&lt;div style={{ marginTop: &#039;10px&#039;, marginBottom: &#039;10px&#039; }}&gt;
            &lt;OverlayTrigger placement=&quot;right&quot; overlay={&lt;Tooltip id=&quot;tooltip&quot;&gt; &lt;p&gt; Events created on {props.value} &lt;/p&gt; &lt;/Tooltip&gt;}&gt;
                &lt;span style={{ color: &#039;#999999&#039;, marginLeft: &#039;10px&#039;, fontStyle: &#039;italic&#039;, fontSize: &#039;16px&#039; }}&gt; &lt;strong&gt; {Moment(props.value).format(&quot;MMM D&quot;)} &lt;/strong&gt; &lt;/span&gt;
            &lt;/OverlayTrigger&gt;
        &lt;/div&gt;)
    } else {
        // used in &#039;monitoring view&#039;
        return (&lt;div style={{ marginTop: &#039;10px&#039;, marginBottom: &#039;10px&#039; }}&gt;
            &lt;OverlayTrigger placement=&quot;right&quot; overlay={&lt;Tooltip id=&quot;tooltip&quot;&gt; &lt;p&gt; Events created on {props.value} &lt;/p&gt; &lt;/Tooltip&gt;}&gt;
                &lt;span style={{ color: &#039;#999999&#039;, marginLeft: &#039;0px&#039;, fontStyle: &#039;italic&#039;, fontSize: &#039;16px&#039; }}&gt; &lt;strong&gt; {Moment(props.value).format(&quot;MMM D&quot;)} &lt;/strong&gt; &lt;/span&gt;
            &lt;/OverlayTrigger&gt;
        &lt;/div&gt;
        )
    }
}

EventList.propTypes = {
    /** the array of unsorted events as provided by the ICAT+ server */
    events: PropTypes.array,
    /** the investigationId the provided events belong to. */
    investigationId: PropTypes.string.isRequired,
    /* Callback function triggered when the user updated an event */
    onEventUpdated: PropTypes.func,
    /** the callback functon which refresh the event list */
    reloadEvents: PropTypes.func.isRequired,
    /** callback function which reverse the sorting of events by date */
    reverseEventsSortingByCreationDate: PropTypes.func.isRequired,
    /** the user who is currently logged in */
    user: PropTypes.object.isRequired,
    /* the selected view to display the events in*/
    view: PropTypes.string.isRequired,
}

export default EventList;
</textarea>
  </div>
</div>

<footer class="footer">
  <div class="container">
    <p>.</p>
  </div>
</footer>

<script type="text/html" id="complexity-popover-template">
  <div class="complexity-notice">
    Complexity : {{ complexity.cyclomatic }} <br>
    Length : {{ complexity.halstead.length }} <br>
    Difficulty : {{ complexity.halstead.difficulty.toFixed(2) }} <br>
    Est # bugs : {{ complexity.halstead.bugs.toFixed(2) }}<br>
  </div>
</script>

<script type="text/javascript" src="../../assets/scripts/bundles/core-bundle.js"></script>
<script type="text/javascript" src="../../assets/scripts/bundles/codemirror.js"></script>
<script type="text/javascript" src="../../assets/scripts/codemirror.markpopovertext.js"></script>
<script type="text/javascript" src="report.js"></script>
<script type="text/javascript" src="report.history.js"></script>
<script type="text/javascript" src="../../assets/scripts/plato-file.js"></script>
</body>
</html>
