<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Plato - components/Event/Tag/TagList.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/Tag/TagList.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">71.31</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">160</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">29.64</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.04</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 React from &#039;react&#039;;
import PropTypes from &#039;prop-types&#039;;
import { Grid, Row, Col } from &#039;react-bootstrap&#039;;
import { TAG_MANAGER_CONTEXT, BASIC_EVENT_CONTEXT, DETAILED_EVENT_CONTEXT, INFO_MESSAGE_TYPE } from &#039;../../../constants/EventTypes&#039;;
import TagViewer from &#039;./TagViewer&#039;;
import CreatableSelect from &#039;react-select/lib/Creatable&#039;;
import _ from &#039;lodash&#039;;
import { GUI_CONFIG } from &#039;../../../config/gui.config&#039;;
import UserMessage from &#039;../../UserMessage&#039;;

/**
 * React component which handles tags (create, edit, remove)
 * @param {*} props tag as provided by the server
 */
class TagList extends React.Component {
    constructor(props) {
        super(props);

        this.onChange = this.onChange.bind(this);
    }

    render() {
        let { availableTags, context } = this.props;


        if (context === DETAILED_EVENT_CONTEXT) {
            // show tags inside a detailed event
            const customStyles = {
                dropdownIndicator: () =&gt; ({
                    display: &#039;none&#039;
                }),

                indicatorSeparator: () =&gt; ({
                    display: &#039;none&#039;
                }),

                control: (provided) =&gt; ({
                    ...provided,
                    maxWidth: 140,
                    minWidth: 100,
                    minHeight: 32,
                }),

                container: (provided) =&gt; ({
                    ...provided,
                    marginTop: &#039;5px&#039;
                }),
            };

            let selectedTags = this.props.selectedTags ?
                this.props.selectedTags.map((tag) =&gt; { return (&lt;TagViewer key={tag._id} context={DETAILED_EVENT_CONTEXT} tag={tag} removeTag={this.props.removeTagFromSelection} /&gt;); })
                : null;
            let availableTagsForSelect = availableTags ?
                availableTags.map((tag) =&gt; ({ value: tag._id, label: tag.name }))
                : null;

            return (
                &lt;div&gt;
                    {selectedTags}

                    &lt;CreatableSelect
                        isClearable={false}
                        noOptionsMessage={() =&gt; &#039;No existing tag&#039;}
                        onChange={this.onChange}
                        styles={customStyles}
                        options={availableTagsForSelect}
                        isSearchable={true} /&gt;

                &lt;/div&gt;
            );

        } else if (context === TAG_MANAGER_CONTEXT) {
            // show tags for management
            if (!availableTags || availableTags.length === 0) {
                return (
                    &lt;Grid fluid={true} &gt;
                        &lt;h3&gt; Tags currently available in this proposal&lt;/h3&gt;
                        &lt;Row style={{ marginLeft: &#039;30px&#039;, marginRight: &#039;30px&#039;, marginTop: &#039;20px&#039; }}&gt;
                            &lt;UserMessage
                                message=&#039;There is no tag in this proposal yet.&#039;
                                isTextCentered={true}
                                type={INFO_MESSAGE_TYPE}
                            /&gt;
                        &lt;/Row&gt;
                    &lt;/Grid &gt;
                );
            } else {
                let detailedTags = [];
                let sortedAvailableTags = _.sortBy(availableTags, [&#039;name&#039;]);
                detailedTags = sortedAvailableTags.map((tag, index) =&gt; { return (&lt;TagViewer context={TAG_MANAGER_CONTEXT} tag={tag} editTag={this.props.editTag} key={index} /&gt;); });
                return (
                    &lt;div style={{ paddingBottom: &#039;70px&#039; }}&gt;
                        &lt;Grid fluid={true} &gt;
                            &lt;h3&gt; Tags currently available in this proposal&lt;/h3&gt;
                            &lt;Row style={{ marginTop: &#039;20px&#039; }}&gt;
                                &lt;Col xs={0} md={1}&gt; &lt;/Col&gt;
                                &lt;Col xs={12} md={10}&gt;
                                    {detailedTags}
                                &lt;/Col&gt;

                                &lt;Col xs={0} md={1}&gt; &lt;/Col&gt;

                            &lt;/Row&gt;
                        &lt;/Grid &gt;
                    &lt;/div&gt;);
            };
        } else if (context === BASIC_EVENT_CONTEXT) {
            let selectedTags = this.props.selectedTags ?
                this.props.selectedTags.map((tag) =&gt; { return (&lt;TagViewer key={tag._id} context={BASIC_EVENT_CONTEXT} tag={tag} removeTag={this.props.removeTagFromSelection} /&gt;); })
                : null;

            return (&lt;div&gt;  {selectedTags} &lt;/div&gt;);
        }

        return null;
    }

    /**
     * Callback function triggered when the input has changed. A new tag is being created
* @param {*} value the new tag as provided by the react-select component
                */
    onChange(option, action) {
        if (option &amp;&amp; action) {
            if (action.action === &#039;create-option&#039;) {
                let newTag = {
                    color: GUI_CONFIG().DEFAULT_TAG_COLOR,
                    description: null,
                    name: option.label,
                    investigationId: this.props.investigationId
                };

                this.props.createNewTag(newTag);
            } else if (action.action === &#039;select-option&#039;) {
                this.props.addTagToSelection(_.find(this.props.availableTags, (tag) =&gt; { return tag._id === option.value; }));
            }
        }
    }
}

TagList.propTypes = {
    /* List of available tags (can be null when there is no available tags yet)*/
    availableTags: PropTypes.array,
    /* Context defining how tag list is rendered */
    context: PropTypes.string.isRequired,
    /* investigation identifier */
    investigationId: PropTypes.string,
    /* List of tags currently selected. Used only in the event context */
    selectedTags: PropTypes.array,
    /* Callback function trigered when the user selects a tag from the available tags. Used only in the EVENT context.*/
    addTagToSelection: PropTypes.func,
    /* Callback function used to create a new tag */
    createNewTag: PropTypes.func,
    /* Callback function trigered when the user click to edit the tag. Used only in the contexct of tag management */
    editTag: PropTypes.func,
    /* Callback function trigered when the user clicks the X on the tag label. Used only in Event context. */
    removeTagFromSelection: PropTypes.func,
};

export default TagList;
</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>
