<commit_before>jQuery(document).ready(function($) {
  function _(message) {
    return message;
  }

  messages = [
    _('My Template'),
    _('Create'),
    _('Delete'),
    _('Save template success: '),
    _('Delete template success: '),
    _('Please input template name (overwriting existing one with equal name).'),
    _('Sure to restore the last edited content?'),
    _('Submit ticket?'),
    _('Replace ticket content with template?'),
    _('')
  ];

  var myTemplateHtml = "
<fieldset><legend>" + "${_('My Template')}" + "</legend><select id='tt_custom_select' name='tt_custom_select' style='width: 10em;'></select>
<input type='button' name='tt_custom_save' value='" + "${_('Create')}" + "' id='tt_custom_save'/><input type='button' name='tt_custom_delete' value='" + "${_('Delete')}" + "' id='tt_custom_delete'/></fieldset>

";
  var rel_url = "tt/";
  var queryResult = null;
  var isLoad = true;

  function _updateTargetElem(ticketType) {
    // for TracWysiwyg
    var wysiwyg_mode = $("#editor-wysiwyg-1:checked").length;
    if (wysiwyg_mode) {
      $("#editor-textarea-1").click();
    }

    for (field in ticketType) {
      // update targetElem value
      var targetElem = document.getElementById('field-' + field);

      if (targetElem) {
        if (targetElem.type == 'checkbox') {
          targetElem.checked = ticketType[field] == 1;
        } else if (targetElem.type == 'select-one') {
          var options = targetElem.getElementsByTagName('option');
          for (var i = 0; i < options.length; i++) {
            var elem = options[i];
            if (elem.text == ticketType[field]) {
              elem.selected = true;
            }
          }
        } else {
          targetElem.value = ticketType[field];
        }
      } else {
        var targetElems = document.getElementsByName('field_' + field);
        for (var i = 0; i < targetElems.length; i++) {
          var elem = targetElems[i];
          if (elem.value == ticketType[field]) {
            if (elem.type == 'checkbox') {
              elem.checked = ticketType[field] == 1;
            }
          }
        }
      }
    }
    // for TracWysiwyg
    if (wysiwyg_mode) {
      $("#editor-wysiwyg-1").click();
    }
  }

  function handleResponseQuery(result) {
    if (result == 0 || result == -1) {
      return;
    }
    queryResult = result;

    if (isLoad == true && queryResult.enable_custom) {
      // custom
      var tt_custom_select = $("#tt_custom_select");
      $("#content").prepend(myTemplateHtml);
      tt_custom_select.append("<option></option>");

      $("#tt_custom_save").click(onCustomSave);
      $("#tt_custom_delete").click(onCustomDelete);
      tt_custom_select.change(onCustomChanged);
      $("#tt_custom_tip").click(onCustomTip);
      // set custom to null
      tt_custom_select.val("");
    }

    // fill custom template select
    var custom_names = [];
    for (name in queryResult.field_value_mapping_custom) {
      custom_names.push(name);
    }
    custom_names.sort();

    for (var i in custom_names) {
      var name = custom_names[i];
      $("#tt_custom_select").append("<option>" + name + "</option>");
    }

    // delete edit_buffer from my template
    tt_custom_select.find("option:contains('edit_buffer')").remove();

    if (isLoad == true) {
      var evt = {"type": "change"};
      // trigger type change
      var params = location.search.slice(1).split("&");
      var ticket_preset = false;
      for (var i = 0; i < params.length; i++) {
        var param = params[i];
        var param_name = param.split("=")[0];
        if (param_name == "description") {
          ticket_preset = true;
          break;
        }
      }

      if (!ticket_preset) {
        $("#field-type").change();
      }

      var reapplyTemplate = result["warning"] != "1" && !preview;
      initTypeChanged(reapplyTemplate);
    }
  }

  function handleResponseSave(jsonStr) {

    var result = JSON.parse(jsonStr, null);
    if (result == 0 || result == -1) {
      return;
    }

    var tt_name = result.tt_name;

    // update field_value_mapping_custom
    queryResult.field_value_mapping_custom[tt_name] = result.new_template;

    // insert options
    var tt_custom_select = $("tt_custom_select");
    if (!tt_custom_select.find("option:contains('" + tt_name + "')").length) {
      var optionNew = '<option>' + tt_name + '</option>';
      tt_custom_select.append(optionNew);
    }

    var tt_custom_tip = $('#tt_custom_tip');
    tt_custom_tip.empty();
    tt_custom_tip.append("${_('Save template success: ')}" + tt_name);
  }

  function handleResponseDelete(jsonStr) {

    var result = JSON.parse(jsonStr, null);
    if (result == 0 || result == -1) {
      return;
    }

    var tt_name = result.tt_name;

    var tt_custom_select = $("tt_custom_select");
    tt_custom_select.find('option:selected').remove();

    // set custom to null
    tt_custom_select.val("");

    var tt_custom_tip = $('#tt_custom_tip');
    tt_custom_tip.empty();
    tt_custom_tip.append("${_('Delete template success: ')}" + tt_name);

  }

  function onCustomChanged(evt) {
    var tt_name = $("#tt_custom_select").val();
    if (!tt_name) {
      return;
    }

    if (evt.type == "change") {
      var answer = confirm("${_('Replace ticket content with template?')}");
      if (!answer) {
        return;
      }
    }

    // apply custom template
    var ticketType = queryResult.field_value_mapping_custom[tt_name];
    _updateTargetElem(ticketType);
  }

  function onCustomTip(evt) {
    $("#tt_custom_tip").empty();
  }

  function onCustomSave(evt) {
    var tt_name = prompt("${_('Please input template name (overwriting existing one with equal name).')}");
    if (!tt_name) {
      return;
    }

    // for TracWysiwyg
    var wysiwyg_mode = $("#editor-wysiwyg-1:checked").length;
    if (wysiwyg_mode) {
      $("#editor-textarea-1").click();
    }

    // get new_template
    var new_template = {};
    for (var i = 0; i < queryResult.field_list.length; i++) {
      var field = queryResult.field_list[i];
      var elem = document.getElementById('field-' + field);
      if (elem) {
        if (elem.type == 'checkbox') {
          if (elem.checked) {
            new_template[field] = 1;
          } else {
            new_template[field] = 0;
          }
        }
        else if (elem.type == 'select-one') {
          var options = elem.getElementsByTagName('option');
          for (var j = 0; j < options.length; j++) {
            if (options[j].selected) {
              new_template[field] = options[j].text;
            }
          }
        } else {
          new_template[field] = elem.value;
        }
      }
    }

    // for TracWysiwyg
    if (wysiwyg_mode) {
      $("#editor-wysiwyg-1").click();
    }

    // dump json string
    data = {
      "tt_name": tt_name,
      "custom_template": new_template
    };
    var json_string = JSON.stringify(data);

    $.ajax(
      {
        cache: false,
        async: true,
        url: rel_url + "custom_save",
        success: handleResponseSave,
        type: "POST",
        contentType: "application/json",
        data: json_string
      }
    );
  }

  function onCustomDelete(evt) {
    var tt_name = $("#tt_custom_select").val();
    if (!tt_name) {
      return;
    }

    // dump json string
    data = {
      "tt_name": tt_name
    };
    var json_string = JSON.stringify(data);

    $.ajax(
      {
        cache: false,
        async: true,
        url: rel_url + "custom_delete",
        success: handleResponseDelete,
        type: "POST",
        contentType: "application/json",
        data: json_string
      }
    );

  }

  function loadEditBuffer(evt) {
    var answer = confirm("${_('Sure to restore the last edited content?')}");
    if (!answer) {
      return;
    }

    // get last ticket field values
    $.getJSON(rel_url + "query", function (result) {
      // replace ticket fields
      queryResult = result;
      var ticketType = queryResult.field_value_mapping_custom["edit_buffer"];
      _updateTargetElem(ticketType);
    });

  }

  function onTypeChanged(evt) {
    var tt_name = $("#field-type").val();
    if (!tt_name) {
      tt_name = $("#field-type", ttTypeCache["Default"]).val();
    }

    if (!queryResult) {
      return;
    }

    if (isLoad) {
      return;
    }

    var ticketType = queryResult.field_value_mapping[tt_name];
    if ($.isEmptyObject(ticketType)) {
      ticketType = queryResult.field_value_mapping['default'];
    }
    if ($.isEmptyObject(ticketType)){
      return;
    }

    var targetElem = document.getElementById('field-description');
    if (evt.type == "change" && isLoad == false && $.trim(targetElem.value) != "") {
      var answer = confirm("${_('Replace ticket content with template?')}");
      if (!answer) {
        return;
      }
    }
    _updateTargetElem(ticketType);
  }

  function initTypeChanged(reapplyTemplate) {
    // reset isLoad
    isLoad = false;

    if (location.href.indexOf("newticket#ticket", location.href.length - "newticket#ticket".length) !== -1) {
      return;
    }

    var tt_name = $("#field-type").val();
    if (!tt_name) {
      tt_name = $("#field-type", ttTypeCache["Default"]).val();
    }

    if (!queryResult) {
      return;
    }

    if (reapplyTemplate) {
      var ticketType = queryResult.field_value_mapping[tt_name];
      if (!ticketType) {
        ticketType = queryResult.field_value_mapping['default'];
      }
      _updateTargetElem(ticketType);
    }
  }

  $("#field-type").change(onTypeChanged);

  // requery
  if ($("#warning").get(0)) {
    $.getJSON("tt/query" + location.search, {warning: "1"}, handleResponseQuery);
  } else {
    $.getJSON("tt/query" + location.search, handleResponseQuery);
  }
});
<commit_msg>Fix the custom select dropdown::<commit_after>jQuery(document).ready(function($) {
  function _(message) {
    return message;
  }

  messages = [
    _('My Template'),
    _('Create'),
    _('Delete'),
    _('Save template success: '),
    _('Delete template success: '),
    _('Please input template name (overwriting existing one with equal name).'),
    _('Sure to restore the last edited content?'),
    _('Submit ticket?'),
    _('Replace ticket content with template?'),
    _('')
  ];

  var myTemplateHtml = "
<fieldset><legend>" + "${_('My Template')}" + "</legend><select id='tt_custom_select' name='tt_custom_select' style='width: 10em;'></select>
<input type='button' name='tt_custom_save' value='" + "${_('Create')}" + "' id='tt_custom_save'/><input type='button' name='tt_custom_delete' value='" + "${_('Delete')}" + "' id='tt_custom_delete'/></fieldset>

";
  var rel_url = "tt/";
  var queryResult = null;
  var isLoad = true;

  function _updateTargetElem(ticketType) {
    // for TracWysiwyg
    var wysiwyg_mode = $("#editor-wysiwyg-1:checked").length;
    if (wysiwyg_mode) {
      $("#editor-textarea-1").click();
    }

    for (field in ticketType) {
      // update targetElem value
      var targetElem = document.getElementById('field-' + field);

      if (targetElem) {
        if (targetElem.type == 'checkbox') {
          targetElem.checked = ticketType[field] == 1;
        } else if (targetElem.type == 'select-one') {
          var options = targetElem.getElementsByTagName('option');
          for (var i = 0; i < options.length; i++) {
            var elem = options[i];
            if (elem.text == ticketType[field]) {
              elem.selected = true;
            }
          }
        } else {
          targetElem.value = ticketType[field];
        }
      } else {
        var targetElems = document.getElementsByName('field_' + field);
        for (var i = 0; i < targetElems.length; i++) {
          var elem = targetElems[i];
          if (elem.value == ticketType[field]) {
            if (elem.type == 'checkbox') {
              elem.checked = ticketType[field] == 1;
            }
          }
        }
      }
    }
    // for TracWysiwyg
    if (wysiwyg_mode) {
      $("#editor-wysiwyg-1").click();
    }
  }

  function handleResponseQuery(result) {
    if (result == 0 || result == -1) {
      return;
    }
    queryResult = result;

    if (isLoad == true && queryResult.enable_custom) {
      // custom
      $("#content").prepend(myTemplateHtml);
      $("#tt_custom_save").click(onCustomSave);
      $("#tt_custom_delete").click(onCustomDelete);
      $("#tt_custom_tip").click(onCustomTip);
    }

    // fill custom template select
    var custom_names = [];
    for (name in queryResult.field_value_mapping_custom) {
      custom_names.push(name);
    }
    custom_names.sort();

    $("#tt_custom_select").append("<option></option>");
    for (var i in custom_names) {
      var name = custom_names[i];
      $("#tt_custom_select").append("<option>" + name + "</option>");
    }
    $("#tt_custom_select").change(onCustomChanged);

    // delete edit_buffer from my template
    $("#tt_custom_select").find("option:contains('edit_buffer')").remove();

    if (isLoad == true) {
      var evt = {"type": "change"};
      // trigger type change
      var params = location.search.slice(1).split("&");
      var ticket_preset = false;
      for (var i = 0; i < params.length; i++) {
        var param = params[i];
        var param_name = param.split("=")[0];
        if (param_name == "description") {
          ticket_preset = true;
          break;
        }
      }

      if (!ticket_preset) {
        $("#field-type").change();
      }

      var reapplyTemplate = result["warning"] != "1" && !preview;
      initTypeChanged(reapplyTemplate);
    }
  }

  function handleResponseSave(jsonStr) {

    var result = JSON.parse(jsonStr, null);
    if (result == 0 || result == -1) {
      return;
    }

    var tt_name = result.tt_name;

    // update field_value_mapping_custom
    queryResult.field_value_mapping_custom[tt_name] = result.new_template;

    // insert options
    var tt_custom_select = $("tt_custom_select");
    if (!tt_custom_select.find("option:contains('" + tt_name + "')").length) {
      var optionNew = '<option>' + tt_name + '</option>';
      tt_custom_select.append(optionNew);
    }

    var tt_custom_tip = $('#tt_custom_tip');
    tt_custom_tip.empty();
    tt_custom_tip.append("${_('Save template success: ')}" + tt_name);
  }

  function handleResponseDelete(jsonStr) {

    var result = JSON.parse(jsonStr, null);
    if (result == 0 || result == -1) {
      return;
    }

    var tt_name = result.tt_name;

    var tt_custom_select = $("tt_custom_select");
    tt_custom_select.find('option:selected').remove();

    // set custom to null
    tt_custom_select.val("");

    var tt_custom_tip = $('#tt_custom_tip');
    tt_custom_tip.empty();
    tt_custom_tip.append("${_('Delete template success: ')}" + tt_name);

  }

  function onCustomChanged(evt) {
    var tt_name = $("#tt_custom_select").val();
    if (!tt_name) {
      return;
    }

    if (evt.type == "change") {
      var answer = confirm("${_('Replace ticket content with template?')}");
      if (!answer) {
        $("#tt_custom_select").val("")
        return;
      }
    }

    // apply custom template
    var ticketType = queryResult.field_value_mapping_custom[tt_name];
    _updateTargetElem(ticketType);
  }

  function onCustomTip(evt) {
    $("#tt_custom_tip").empty();
  }

  function onCustomSave(evt) {
    var tt_name = prompt("${_('Please input template name (overwriting existing one with equal name).')}");
    if (!tt_name) {
      return;
    }

    // for TracWysiwyg
    var wysiwyg_mode = $("#editor-wysiwyg-1:checked").length;
    if (wysiwyg_mode) {
      $("#editor-textarea-1").click();
    }

    // get new_template
    var new_template = {};
    for (var i = 0; i < queryResult.field_list.length; i++) {
      var field = queryResult.field_list[i];
      var elem = document.getElementById('field-' + field);
      if (elem) {
        if (elem.type == 'checkbox') {
          if (elem.checked) {
            new_template[field] = 1;
          } else {
            new_template[field] = 0;
          }
        }
        else if (elem.type == 'select-one') {
          var options = elem.getElementsByTagName('option');
          for (var j = 0; j < options.length; j++) {
            if (options[j].selected) {
              new_template[field] = options[j].text;
            }
          }
        } else {
          new_template[field] = elem.value;
        }
      }
    }

    // for TracWysiwyg
    if (wysiwyg_mode) {
      $("#editor-wysiwyg-1").click();
    }

    // dump json string
    data = {
      "tt_name": tt_name,
      "custom_template": new_template
    };
    var json_string = JSON.stringify(data);

    $.ajax(
      {
        cache: false,
        async: true,
        url: rel_url + "custom_save",
        success: handleResponseSave,
        type: "POST",
        contentType: "application/json",
        data: json_string
      }
    );
  }

  function onCustomDelete(evt) {
    var tt_name = $("#tt_custom_select").val();
    if (!tt_name) {
      return;
    }

    // dump json string
    data = {
      "tt_name": tt_name
    };
    var json_string = JSON.stringify(data);

    $.ajax(
      {
        cache: false,
        async: true,
        url: rel_url + "custom_delete",
        success: handleResponseDelete,
        type: "POST",
        contentType: "application/json",
        data: json_string
      }
    );

  }

  function loadEditBuffer(evt) {
    var answer = confirm("${_('Sure to restore the last edited content?')}");
    if (!answer) {
      return;
    }

    // get last ticket field values
    $.getJSON(rel_url + "query", function (result) {
      // replace ticket fields
      queryResult = result;
      var ticketType = queryResult.field_value_mapping_custom["edit_buffer"];
      _updateTargetElem(ticketType);
    });

  }

  function onTypeChanged(evt) {
    var tt_name = $("#field-type").val();
    if (!tt_name) {
      tt_name = $("#field-type", ttTypeCache["Default"]).val();
    }

    if (!queryResult) {
      return;
    }

    if (isLoad) {
      return;
    }

    var ticketType = queryResult.field_value_mapping[tt_name];
    if ($.isEmptyObject(ticketType)) {
      ticketType = queryResult.field_value_mapping['default'];
    }
    if ($.isEmptyObject(ticketType)){
      return;
    }

    var targetElem = document.getElementById('field-description');
    if (evt.type == "change" && isLoad == false && $.trim(targetElem.value) != "") {
      var answer = confirm("${_('Replace ticket content with template?')}");
      if (!answer) {
        return;
      }
    }
    _updateTargetElem(ticketType);
  }

  function initTypeChanged(reapplyTemplate) {
    // reset isLoad
    isLoad = false;

    if (location.href.indexOf("newticket#ticket", location.href.length - "newticket#ticket".length) !== -1) {
      return;
    }

    var tt_name = $("#field-type").val();
    if (!tt_name) {
      tt_name = $("#field-type", ttTypeCache["Default"]).val();
    }

    if (!queryResult) {
      return;
    }

    if (reapplyTemplate) {
      var ticketType = queryResult.field_value_mapping[tt_name];
      if (!ticketType) {
        ticketType = queryResult.field_value_mapping['default'];
      }
      _updateTargetElem(ticketType);
    }
  }

  $("#field-type").change(onTypeChanged);

  // requery
  if ($("#warning").get(0)) {
    $.getJSON("tt/query" + location.search, {warning: "1"}, handleResponseQuery);
  } else {
    $.getJSON("tt/query" + location.search, handleResponseQuery);
  }
});
<|endoftext|>


<commit_before>/**
 * @file CascaderListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, Fragment} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import Theme from '../Theme';
import IconButton from '../IconButton';
import Radio from '../Radio';
import Checkbox from '../Checkbox';
import List from '../List';

import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';

class CascaderListItem extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            activatedIndex: -1
        };

    }

    // toggleTreeNode = e => {
    //
    //     e.stopPropagation();
    //
    //     const {onNodeToggleStart} = this.props;
    //     onNodeToggleStart && onNodeToggleStart();
    //
    //     this.setState({
    //         collapsed: !this.state.collapsed
    //     }, () => {
    //         const {onNodeToggleEnd} = this.props;
    //         onNodeToggleEnd && onNodeToggleEnd();
    //     });
    //
    // };

    // checkboxChangeHandler = e => {
    //
    //     const {data, path, value, onSelect, onDeselect} = this.props;
    //
    //     if (!Calculation.isItemChecked(data, value, this.props)) {
    //         onSelect && onSelect(data, path, e);
    //     } else {
    //         onDeselect && onDeselect(data, path, e);
    //     }
    //
    // };
    //
    // radioChangeHandler = e => {
    //     const {data, path, onSelect} = this.props;
    //     onSelect && onSelect(data, path, e);
    // };
    //
    // listItemClickHanlder = e => {
    //
    //     e.preventDefault();
    //
    //     const {data, path, disabled, isLoading, readOnly} = this.props;
    //
    //     if (disabled || isLoading || readOnly || data.disabled || data.isLoading || data.readOnly) {
    //         return;
    //     }
    //
    //     const {onClick} = this.props;
    //     onClick && onClick(data, path, e);
    //
    //     const {selectMode} = this.props;
    //
    //     switch (selectMode) {
    //         case SelectMode.MULTI_SELECT:
    //             this.checkboxChangeHandler(e);
    //             return;
    //         case SelectMode.SINGLE_SELECT:
    //             this.radioChangeHandler(e);
    //             return;
    //     }
    //
    // };

    isExpanded = (node, index) => {
        return index === this.state.activatedIndex && node.children && node.children.length > 0;
    };

    getCurrentPathNode = (index = this.state.activatedIndex) => {

        const {data} = this.props;

        return index > -1 ?
            {index: index, node: data[index]}
            :
            null;

    };

    getPath = (index = this.state.activatedIndex) => {

        const {path} = this.props,
            currentPathNode = this.getCurrentPathNode(index);

        return path ?
            [...path, currentPathNode]
            :
            [currentPathNode];

    };

    listItemRenderer = (node, index) => {

        const {valueField, displayField, descriptionField, renderer} = this.props;

        let text, desc;
        if (!renderer) {
            text = Util.getTextByDisplayField(node, displayField, valueField);
            desc = node[descriptionField] || null;
        }

        return (
            <Fragment>

                {
                    renderer ?
                        renderer(node, index)
                        :
                        (
                            desc ?

                                        {text}

                                        {desc}

                                :
                                text
                        )
                }

                {
                    this.isExpanded(node, index) ?

                        :
                        null
                }

            </Fragment>
        );

    };

    listItemClickHanlder = (node, index) => {

        const {data, disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly || data.disabled || data.isLoading || data.readOnly) {
            return;
        }

        this.setState({
            activatedIndex: index
        }, () => {
            const {onClick} = this.props;
            onClick && onClick(node, index);
        });

    };

    listItemSelectHanlder = (node, index) => {
        const {onSelect} = this.props;
        onSelect && onSelect(node, this.getPath(index));
    };

    listItemDeselectHanlder = (node, index) => {
        const {onDeselect} = this.props;
        onDeselect && onDeselect(node, this.getPath(index));
    };

    render() {

        const {

                index, depth, path, theme, listWidth, selectTheme, selectMode, data, value,
                disabled, isLoading, readOnly, allowCollapse, isSelectRecursive,
                valueField, displayField, descriptionField,

                collapsedIconCls, expandedIconCls, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                renderer, onSelect, onDeselect, onMouseEnter, onMouseLeave

            } = this.props,
            {activatedIndex} = this.state,

            listClassName = classNames('cascader-popup-list', {
                first: depth === 0
            }),
            listStyle = {
                width: listWidth
            };

        // checked = Calculation.isItemChecked(data, value, this.props),
        // indeterminate = Calculation.isItemIndeterminate(data, value, this.props),
        //
        // isNodeLoading = data.isLoading || isLoading,
        // isNodeDisabled = data.disabled || disabled || isNodeLoading,
        //
        // nodeClassName = classNames('tree-node', {
        //     [`theme-${theme}`]: theme,
        //     [data.className]: data.className
        // }),
        // nodeStyle = {
        //     ...data.style,
        //     paddingLeft: (depth + 1) * 20
        // },
        //
        // childrenClassName = classNames('tree-node-children', {
        //     collapsed
        // }),
        //
        // loadingIconPosition = (data.rightIconCls && !data.iconCls) ? 'right' : 'left';

        return (

                <List className={listClassName}
                      style={listStyle}
                      data={data}
                      renderer={this.listItemRenderer}
                      onItemClick={this.listItemClickHanlder}
                      onItemSelect={this.listItemSelectHanlder}
                      onItemDeselect={this.listItemDeselectHanlder}/>

                {
                    activatedIndex > -1 && data[activatedIndex].children && data[activatedIndex].children.length > 0 ?
                        <CascaderListItem {...this.props}
                                          data={data[activatedIndex].children}
                                          depth={depth + 1}
                                          path={this.getPath()}/>
                        :
                        null
                }

        );

        // return (
        //

        //
        //         <TipProvider className='block'
        //                      text={data.tip}
        //                      position={data.tipPosition}>
        //
        //

        //
        //

        //
        //                     {
        //                         allowCollapse && data.children && data.children.length > 0 ?
        //                             <IconButton className="tree-node-collapse-icon"
        //                                         iconCls={collapsed ?
        //                                             data.collapsedIconCls || collapsedIconCls
        //                                             :
        //                                             data.expandedIconCls || expandedIconCls}
        //                                         onClick={this.toggleTreeNode}/>
        //                             :
        //                             null
        //                     }
        //
        //                     {
        //                         selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
        //                             <Radio className="tree-node-select"
        //                                    theme={selectTheme}
        //                                    checked={checked}
        //                                    disabled={isNodeDisabled}
        //                                    uncheckedIconCls={data.radioUncheckedIconCls || radioUncheckedIconCls}
        //                                    checkedIconCls={data.radioCheckedIconCls || radioCheckedIconCls}
        //                                    disableTouchRipple={true}/>
        //                             :
        //                             null
        //                     }
        //
        //                     {
        //                         selectMode === SelectMode.MULTI_SELECT ?
        //                             <Checkbox className="tree-node-select"
        //                                       theme={selectTheme}
        //                                       checked={checked}
        //                                       indeterminate={isSelectRecursive ? indeterminate : false}
        //                                       disabled={isNodeDisabled}
        //                                       uncheckedIconCls={data.checkboxUncheckedIconCls || checkboxUncheckedIconCls}
        //                                       checkedIconCls={data.checkboxCheckedIconCls || checkboxCheckedIconCls}
        //                                       indeterminateIconCls={data.checkboxIndeterminateIconCls || checkboxIndeterminateIconCls}
        //                                       disableTouchRipple={true}/>
        //                             :
        //                             null
        //                     }
        //
        //                     {
        //                         isNodeLoading && loadingIconPosition === 'left' ?
        //

        //                                 <CircularLoading className="button-loading-icon"
        //                                                  size="small"/>
        //

        //                             :
        //                             (
        //                                 data.iconCls ?
        //                                     <i className={`button-icon button-icon-left ${data.iconCls}`}
        //                                        aria-hidden="true">
        //                                     :
        //                                     null
        //                             )
        //                     }
        //
        //                     {
        //                         data.itemRenderer && typeof data.itemRenderer === 'function' ?
        //                             data.itemRenderer(data, index)
        //                             :
        //                             (
        //                                 renderer && typeof renderer === 'function' ?
        //                                     renderer(data, index)
        //                                     :
        //                                     (
        //                                         data[descriptionField] ?
        //

        //
        //                                                 {Util.getTextByDisplayField(data, displayField, valueField)}
        //
        //
        //                                                 {data[descriptionField]}
        //
        //

        //                                             :
        //                                             Util.getTextByDisplayField(data, displayField, valueField)
        //                                     )
        //                             )
        //                     }
        //
        //                     {
        //                         isNodeLoading && loadingIconPosition === 'right' ?
        //                             <CircularLoading className="button-icon button-icon-right button-loading-icon"
        //                                              size="small"/>
        //                             :
        //                             (
        //                                 data.rightIconCls ?
        //                                     <i className={`button-icon button-icon-right ${data.rightIconCls}`}
        //                                        aria-hidden="true">
        //                                     :
        //                                     null
        //                             )
        //                     }
        //

        //
        //

        //         </TipProvider>
        //
        //         {
        //             data.children && data.children.length > 0 ?
        //

        //                     {
        //                         data.children.map((item, index) =>
        //                             <CascaderListItem {...this.props}
        //                                               key={index}
        //                                               data={item}
        //                                               index={index}
        //                                               depth={depth + 1}
        //                                               path={
        //                                                   path ?
        //                                                       [...path, {index, node: item}]
        //                                                       :
        //                                                       [{index, node: item}]
        //                                               }/>
        //                         )
        //                     }
        //

        //                 :
        //                 null
        //         }
        //
        //

        // );

    }
}

CascaderListItem.propTypes = {

    index: PropTypes.number,
    depth: PropTypes.number,
    path: PropTypes.array,

    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    listWidth: PropTypes.number,

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.array,
    value: PropTypes.any,

    valueField: PropTypes.string,
    displayField: PropTypes.string,
    descriptionField: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    readOnly: PropTypes.bool,
    allowCollapse: PropTypes.bool,
    isNodeToggling: PropTypes.bool,
    isSelectRecursive: PropTypes.bool,

    renderer: PropTypes.func,

    collapsedIconCls: PropTypes.string,
    expandedIconCls: PropTypes.string,
    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    onClick: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func,
    onNodeToggleStart: PropTypes.func,
    onNodeToggleEnd: PropTypes.func

};

CascaderListItem.defaultProps = {

    index: 0,
    depth: 0,

    theme: Theme.DEFAULT,
    listWidth: 200,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',

    disabled: false,
    isLoading: false,
    readOnly: false,
    allowCollapse: true,
    isNodeToggling: false,
    isSelectRecursive: false,

    tipPosition: Position.BOTTOM,

    collapsedIconCls: 'fas fa-caret-right',
    expandedIconCls: 'fas fa-caret-down',
    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square'

};

export default CascaderListItem;<commit_msg>update CascaderListItem<commit_after>/**
 * @file CascaderListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, Fragment} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import Theme from '../Theme';
import IconButton from '../IconButton';
import Radio from '../Radio';
import Checkbox from '../Checkbox';
import List from '../List';

import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';

class CascaderListItem extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            activatedIndex: -1
        };

    }

    // toggleTreeNode = e => {
    //
    //     e.stopPropagation();
    //
    //     const {onNodeToggleStart} = this.props;
    //     onNodeToggleStart && onNodeToggleStart();
    //
    //     this.setState({
    //         collapsed: !this.state.collapsed
    //     }, () => {
    //         const {onNodeToggleEnd} = this.props;
    //         onNodeToggleEnd && onNodeToggleEnd();
    //     });
    //
    // };

    // checkboxChangeHandler = e => {
    //
    //     const {data, path, value, onSelect, onDeselect} = this.props;
    //
    //     if (!Calculation.isItemChecked(data, value, this.props)) {
    //         onSelect && onSelect(data, path, e);
    //     } else {
    //         onDeselect && onDeselect(data, path, e);
    //     }
    //
    // };
    //
    // radioChangeHandler = e => {
    //     const {data, path, onSelect} = this.props;
    //     onSelect && onSelect(data, path, e);
    // };
    //
    // listItemClickHanlder = e => {
    //
    //     e.preventDefault();
    //
    //     const {data, path, disabled, isLoading, readOnly} = this.props;
    //
    //     if (disabled || isLoading || readOnly || data.disabled || data.isLoading || data.readOnly) {
    //         return;
    //     }
    //
    //     const {onClick} = this.props;
    //     onClick && onClick(data, path, e);
    //
    //     const {selectMode} = this.props;
    //
    //     switch (selectMode) {
    //         case SelectMode.MULTI_SELECT:
    //             this.checkboxChangeHandler(e);
    //             return;
    //         case SelectMode.SINGLE_SELECT:
    //             this.radioChangeHandler(e);
    //             return;
    //     }
    //
    // };

    isExpanded = (node, index) => {
        return index === this.state.activatedIndex && node.children && node.children.length > 0;
    };

    getCurrentPathNode = (index = this.state.activatedIndex) => {

        const {data} = this.props;

        return index > -1 ?
            {index: index, node: data[index]}
            :
            null;

    };

    getPath = (index = this.state.activatedIndex) => {

        const {path} = this.props,
            currentPathNode = this.getCurrentPathNode(index);

        return path ?
            [...path, currentPathNode]
            :
            [currentPathNode];

    };

    listItemRenderer = (node, index) => {

        const {valueField, displayField, descriptionField, renderer} = this.props;

        let text, desc;
        if (!renderer) {
            text = Util.getTextByDisplayField(node, displayField, valueField);
            desc = node[descriptionField] || null;
        }

        return (
            <Fragment>

                {
                    renderer ?
                        renderer(node, index)
                        :
                        (
                            desc ?

                                        {text}

                                        {desc}

                                :
                                text
                        )
                }

                {
                    this.isExpanded(node, index) ?

                        :
                        null
                }

            </Fragment>
        );

    };

    listItemClickHanlder = (node, index) => {

        const {data, disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly || data.disabled || data.isLoading || data.readOnly) {
            return;
        }

        this.setState({
            activatedIndex: index
        }, () => {
            const {onClick} = this.props;
            onClick && onClick(node, index);
        });

    };

    listItemSelectHanlder = (node, index) => {
        const {onSelect} = this.props;
        onSelect && onSelect(node, this.getPath(index));
    };

    listItemDeselectHanlder = (node, index) => {
        const {onDeselect} = this.props;
        onDeselect && onDeselect(node, this.getPath(index));
    };

    render() {

        const {

                index, depth, path, theme, listWidth, selectTheme, selectMode, data, value,
                disabled, isLoading, readOnly, allowCollapse, isSelectRecursive,
                valueField, displayField, descriptionField,

                collapsedIconCls, expandedIconCls, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                renderer, onSelect, onDeselect, onMouseEnter, onMouseLeave

            } = this.props,
            {activatedIndex} = this.state,

            listClassName = classNames('cascader-popup-list', {
                first: depth === 0
            }),
            listStyle = {
                width: listWidth
            };

        // checked = Calculation.isItemChecked(data, value, this.props),
        // indeterminate = Calculation.isItemIndeterminate(data, value, this.props),
        //
        // isNodeLoading = data.isLoading || isLoading,
        // isNodeDisabled = data.disabled || disabled || isNodeLoading,
        //
        // nodeClassName = classNames('tree-node', {
        //     [`theme-${theme}`]: theme,
        //     [data.className]: data.className
        // }),
        // nodeStyle = {
        //     ...data.style,
        //     paddingLeft: (depth + 1) * 20
        // },
        //
        // childrenClassName = classNames('tree-node-children', {
        //     collapsed
        // }),
        //
        // loadingIconPosition = (data.rightIconCls && !data.iconCls) ? 'right' : 'left';

        return (

                <List className={listClassName}
                      style={listStyle}
                      selectMode={selectMode}
                      data={data}
                      value={value}
                      renderer={this.listItemRenderer}
                      onItemClick={this.listItemClickHanlder}
                      onItemSelect={this.listItemSelectHanlder}
                      onItemDeselect={this.listItemDeselectHanlder}/>

                {
                    activatedIndex > -1 && data[activatedIndex].children && data[activatedIndex].children.length > 0 ?
                        <CascaderListItem {...this.props}
                                          data={data[activatedIndex].children}
                                          depth={depth + 1}
                                          path={this.getPath()}/>
                        :
                        null
                }

        );

        // return (
        //

        //
        //         <TipProvider className='block'
        //                      text={data.tip}
        //                      position={data.tipPosition}>
        //
        //

        //
        //

        //
        //                     {
        //                         allowCollapse && data.children && data.children.length > 0 ?
        //                             <IconButton className="tree-node-collapse-icon"
        //                                         iconCls={collapsed ?
        //                                             data.collapsedIconCls || collapsedIconCls
        //                                             :
        //                                             data.expandedIconCls || expandedIconCls}
        //                                         onClick={this.toggleTreeNode}/>
        //                             :
        //                             null
        //                     }
        //
        //                     {
        //                         selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
        //                             <Radio className="tree-node-select"
        //                                    theme={selectTheme}
        //                                    checked={checked}
        //                                    disabled={isNodeDisabled}
        //                                    uncheckedIconCls={data.radioUncheckedIconCls || radioUncheckedIconCls}
        //                                    checkedIconCls={data.radioCheckedIconCls || radioCheckedIconCls}
        //                                    disableTouchRipple={true}/>
        //                             :
        //                             null
        //                     }
        //
        //                     {
        //                         selectMode === SelectMode.MULTI_SELECT ?
        //                             <Checkbox className="tree-node-select"
        //                                       theme={selectTheme}
        //                                       checked={checked}
        //                                       indeterminate={isSelectRecursive ? indeterminate : false}
        //                                       disabled={isNodeDisabled}
        //                                       uncheckedIconCls={data.checkboxUncheckedIconCls || checkboxUncheckedIconCls}
        //                                       checkedIconCls={data.checkboxCheckedIconCls || checkboxCheckedIconCls}
        //                                       indeterminateIconCls={data.checkboxIndeterminateIconCls || checkboxIndeterminateIconCls}
        //                                       disableTouchRipple={true}/>
        //                             :
        //                             null
        //                     }
        //
        //                     {
        //                         isNodeLoading && loadingIconPosition === 'left' ?
        //

        //                                 <CircularLoading className="button-loading-icon"
        //                                                  size="small"/>
        //

        //                             :
        //                             (
        //                                 data.iconCls ?
        //                                     <i className={`button-icon button-icon-left ${data.iconCls}`}
        //                                        aria-hidden="true">
        //                                     :
        //                                     null
        //                             )
        //                     }
        //
        //                     {
        //                         data.itemRenderer && typeof data.itemRenderer === 'function' ?
        //                             data.itemRenderer(data, index)
        //                             :
        //                             (
        //                                 renderer && typeof renderer === 'function' ?
        //                                     renderer(data, index)
        //                                     :
        //                                     (
        //                                         data[descriptionField] ?
        //

        //
        //                                                 {Util.getTextByDisplayField(data, displayField, valueField)}
        //
        //
        //                                                 {data[descriptionField]}
        //
        //

        //                                             :
        //                                             Util.getTextByDisplayField(data, displayField, valueField)
        //                                     )
        //                             )
        //                     }
        //
        //                     {
        //                         isNodeLoading && loadingIconPosition === 'right' ?
        //                             <CircularLoading className="button-icon button-icon-right button-loading-icon"
        //                                              size="small"/>
        //                             :
        //                             (
        //                                 data.rightIconCls ?
        //                                     <i className={`button-icon button-icon-right ${data.rightIconCls}`}
        //                                        aria-hidden="true">
        //                                     :
        //                                     null
        //                             )
        //                     }
        //

        //
        //

        //         </TipProvider>
        //
        //         {
        //             data.children && data.children.length > 0 ?
        //

        //                     {
        //                         data.children.map((item, index) =>
        //                             <CascaderListItem {...this.props}
        //                                               key={index}
        //                                               data={item}
        //                                               index={index}
        //                                               depth={depth + 1}
        //                                               path={
        //                                                   path ?
        //                                                       [...path, {index, node: item}]
        //                                                       :
        //                                                       [{index, node: item}]
        //                                               }/>
        //                         )
        //                     }
        //

        //                 :
        //                 null
        //         }
        //
        //

        // );

    }
}

CascaderListItem.propTypes = {

    index: PropTypes.number,
    depth: PropTypes.number,
    path: PropTypes.array,

    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    listWidth: PropTypes.number,

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.array,
    value: PropTypes.any,

    valueField: PropTypes.string,
    displayField: PropTypes.string,
    descriptionField: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    readOnly: PropTypes.bool,
    allowCollapse: PropTypes.bool,
    isNodeToggling: PropTypes.bool,
    isSelectRecursive: PropTypes.bool,

    renderer: PropTypes.func,

    collapsedIconCls: PropTypes.string,
    expandedIconCls: PropTypes.string,
    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    onClick: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func,
    onNodeToggleStart: PropTypes.func,
    onNodeToggleEnd: PropTypes.func

};

CascaderListItem.defaultProps = {

    index: 0,
    depth: 0,

    theme: Theme.DEFAULT,
    listWidth: 200,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',

    disabled: false,
    isLoading: false,
    readOnly: false,
    allowCollapse: true,
    isNodeToggling: false,
    isSelectRecursive: false,

    tipPosition: Position.BOTTOM,

    collapsedIconCls: 'fas fa-caret-right',
    expandedIconCls: 'fas fa-caret-down',
    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square'

};

export default CascaderListItem;<|endoftext|>


<commit_before>var ConsultasApi = require('../shared/consultas');
var request = require('request');
var _ = require('lodash');
var config = require("../shared/config")
var io = require('socket.io-client')(config.DIRECCION_NOTIFICACIONES);

var docentes = [
  "tu vieja", "mapache", "rodri042docente", "jaimito", "lima_nueva", "laCajaDeCamello"
];

function responderConsultaRandom(){
  var consulta;
  ConsultasApi.all(function(consultas){
    console.log(consultas);
    if(_.isEmpty(consultas)){
      return console.log("No hay consultas :(");
     }
    consulta = _.sample(consultas);
    console.log("Escribiendo respuesta");
    io.emit("respondiendo", consulta);
    setTimeout(function() {
      var respuesta = {
        remitente: _.sample(docentes),
        mensaje: "Si si, dale para adelante con eso."
      };
      ConsultasApi.responder(consulta, respuesta,
        function(data){ console.log("Respuesta enviada:" + JSON.stringify(data.body)) },
        function(err){ console.log("ERROR"); console.log(err) });
    }, 2000);
  }, function(err){
    console.log(err);
  })
};

//Escucho
io.on("consultas", function(consulta) { console.log("Nueva consulta: " + JSON.stringify(consulta)) })

io.on("respuestas", function(respuesta) { console.log("Respondieron una consulta: " + JSON.stringify(respuesta)) })

io.on("respondiendo", function(consulta) { console.log("Estan respondiendo: " + JSON.stringify(consulta)) })

//Suscribo
io.emit("suscribir", "respondiendo");

setTimeout(responderConsultaRandom, 2000);
setTimeout(responderConsultaRandom, 4000);
<commit_msg>Fix del respondiendo<commit_after>var ConsultasApi = require('../shared/consultas');
var request = require('request');
var _ = require('lodash');
var config = require("../shared/config")
var io = require('socket.io-client')(config.DIRECCION_NOTIFICACIONES);

var docentes = [
  "tu vieja", "mapache", "rodri042docente", "jaimito", "lima_nueva", "laCajaDeCamello"
];

function responderConsultaRandom(){
  var consulta, docente;
  ConsultasApi.all(function(consultas){
    console.log(consultas);
    if(_.isEmpty(consultas)){
      return console.log("No hay consultas :(");
     }
    consulta = _.sample(consultas);
    docente = _.sample(docentes),
    console.log("Escribiendo respuesta");
    io.emit("respondiendo", { consultaId: consulta.id, remitente: docente });
    setTimeout(function() {
      var respuesta = {
        remitente: docente,
        mensaje: "Si si, dale para adelante con eso."
      };
      ConsultasApi.responder(consulta, respuesta,
        function(data){ console.log("Respuesta enviada:" + JSON.stringify(data.body)) },
        function(err){ console.log("ERROR"); console.log(err) });
    }, 2000);
  }, function(err){
    console.log(err);
  })
};

//Escucho
io.on("consultas", function(consulta) { console.log("Nueva consulta: " + JSON.stringify(consulta)) })

io.on("respuestas", function(respuesta) { console.log("Respondieron una consulta: " + JSON.stringify(respuesta)) })

io.on("respondiendo", function(consulta) { console.log("Estan respondiendo: " + JSON.stringify(consulta)) })

//Suscribo
io.emit("suscribir", "respondiendo");

setTimeout(responderConsultaRandom, 2000);
setTimeout(responderConsultaRandom, 4000);
<|endoftext|>


<commit_before>//add to d3js prototype
d3.selection.prototype.moveToFront = function() {
							return this.each(function(){
							this.parentNode.appendChild(this);
						});
					};

// far left filter scripts
filterStates = [{party: "null"}, {majoritylow: NaN}, {majorityhigh: NaN}, {region: "null"}]

seatsAfterFilter = []

function filterMap(){

	var	party  = filterStates[0].party;
	var majoritylow = filterStates[1].majoritylow;
	var majorityhigh = filterStates[2].majorityhigh;
	var region = filterStates[3].region;

	if (isNaN(majoritylow))
		majoritylow = 0
	if (isNaN(majorityhigh))
		majorityhigh = 1000000

	seatsAfterFilter = [];

	d3.json("map.json", function(uk){

		if (party == "null" && majority == "null" && majoritylow == NaN && majorityhigh == NaN)
			g.selectAll(".map")
				.attr("style", "opacity:1")

		else
			g.selectAll(".map")
				.attr("id", "filtertime")

			if (party == "null")
				g.selectAll("#filtertime")
					.attr("id", "partyfiltered")
			else
				g.selectAll("#filtertime")
					.attr("style", function(d){
						if (party != d.properties.incumbent)
							return "opacity: 0.1";
						})
					.attr("id", function(d){
						if (party == d.properties.incumbent)
							return "partyfiltered"
						});

			g.selectAll("#partyfiltered")
				.attr("style", function(d) {
					if (d.properties.info_majorityvotes < majoritylow || d.properties.info_majorityvotes > majorityhigh )
						return "opacity: 0.1"
					})
				.attr("id", function(d) {
					if (d.properties.info_majorityvotes >= majoritylow && d.properties.info_majorityvotes <=majorityhigh )
						return "majorityfiltered";
					});

			if (region == "null")
				g.selectAll("#majorityfiltered")
					.attr("id", function(d){
							seatsAfterFilter.push(d)

						})
			else
				g.selectAll("#majorityfiltered")
					.attr("style", function(d){
						if (region != d.properties.region)
							return "opacity: 0.1";
					})
					.attr("id", function(d){
						if (region == d.properties.region)
							seatsAfterFilter.push(d);
					});

			g.selectAll(".map")
				.attr("id", function(d) {
					return "i" + d.properties.info_id
				});
			$("#totalfilteredseats").html(" ");
			$("#filteredlisttable").html(" ");

		});
	}

function resetFilter(){

	filterStates[0].party = "null"
	filterStates[1].majoritylow = NaN
	filterStates[2].majorityhigh = NaN
	filterStates[3].region = "null"
	filterMap();

	$("#dropdownparty option:eq(0)").prop("selected", true);
	$("#majority").get(0).reset()
	$("#dropdownregion option:eq(0)").prop("selected", true);

	$("#totalfilteredseats").html(" ");
	$("#filteredlisttable").html(" ");
}

function generateSeatList(){
			$("#totalfilteredseats").html(" ");
			$("#filteredlisttable").html(" ");

			$("#totalfilteredseats").append("
Total : " + seatsAfterFilter.length + "
");
			$.each(seatsAfterFilter, function(i){
				$("#filteredlisttable").append("
" + seatsAfterFilter[i].properties.name + "
")

			});

		}

function zoomToClickedFilteredSeat(d){
	var id = "#i" + d.properties.info_id

	// redo this at some point so not just repeating code.

	previous = d3.select(previousnode)
	current = d3.select(id);
	repeat();

	function repeat(){
		previous.transition()
			.attr("opacity", 1)

		current.transition()
			.duration(1500)
			.attr("opacity", 1)
		.transition()
			.duration(1500)
			.attr("opacity", 0.2)
		.each("end", repeat);
		}

	var bounds = path.bounds(d),
		dx = bounds[1][0] - bounds[0][0],
		dy = bounds[1][1] - bounds[0][1],
		x = (bounds[0][0] + bounds[1][0]) / 2,
		y = (bounds[0][1] + bounds[1][1]) / 2,
		scale = .2 / Math.max(dx / width, dy / height * 2),
		translate = [width / 2 - scale * x, height / 2 - scale * y];

	svg.transition()
		.duration(2500)
		.call(zoom.translate(translate).scale(scale).event);

	seatinfo(d);
	previousnode = id;
	}

// scripts for zoom/pan/clicked

function clicked(d) {

	previous = d3.select(previousnode)
	current = d3.select(this);
	repeat();

	function repeat(){
		previous.transition()
			.attr("opacity", 1)

		current.transition()
			.duration(1500)
			.attr("opacity", 1)
		.transition()
			.duration(1500)
			.attr("opacity", 0.2)
		.each("end", repeat);
		}

	var bounds = path.bounds(d),
		dx = bounds[1][0] - bounds[0][0],
		dy = bounds[1][1] - bounds[0][1],
		x = (bounds[0][0] + bounds[1][0]) / 2,
		y = (bounds[0][1] + bounds[1][1]) / 2,
		scale = .2 / Math.max(dx /  width,  dy / height),
		translate = [width / 2 - scale * x, height / 2 - scale * y];

	svg.transition()
		.duration(2500)
		.call(zoom.translate(translate).scale(scale).event);

	seatinfo(d);
	previousnode = this;

}

function reset() {

	svg.transition()
		.duration(2500)
		.call(zoom.translate([0, 0]).scale(1).event);

}

function zoomed() {
	g.style("stroke-width", 1.5 / d3.event.scale + "px");
	g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");

}

function stopped() {
	if (d3.event.defaultPrevented) d3.event.stopPropagation();
}

// seatinfo on right

var oldclass = null;

function seatinfo(d){

	$("#information").removeClass(oldclass);
	$("#information").addClass(d.properties.incumbent).css("opacity", 0.8);
	$("#information-seatname").html("Seat	 " + d.properties.name +
		"	" + regionlist[d.properties.region] + "	");
	if (d.properties.info_bielection == "yes")
		$("#information-byelection").html("*");
	$("#information-party").html("Party	" + partylist[d.properties.incumbent] + "	");
	$("#information-mp").html("MP	" + d.properties.info_mpfirstname + " " + d.properties.info_mplastname + "	");
	$("#information-majority").html("Majority	 " + d.properties.info_majorityvotes  + "  =  " + d.properties.info_majoritypercent + "%	");
	$("#information-electorate").html("Turnout 	" + d.properties.info_votescast + " = " + d.properties.info_turnout +
		"%	Electorate: " + d.properties.info_electorate + "	");
	$("#information-pie").html(piechart(d));

	oldclass = d.properties.incumbent;
}

function piechart(d){

	$("#information-pie").empty();
	$("#information-chart").empty();

	$("#information-chart").html("

");

	var data = [];
	data.push({ party: "labour", votes: d.properties.info_LAB});
	data.push({ party: "conservative", votes: d.properties.info_CON});
	data.push({ party: "libdems", votes: d.properties.info_LIB});
	data.push({ party: "ukip", votes: d.properties.info_UKIP});
	data.push({ party: "snp", votes: d.properties.info_SNP});
	data.push({ party: "plaidcymru", votes: d.properties.info_PC});
	data.push({ party: "green", votes: d.properties.info_GRN});
	data.push({ party: "other1", votes: d.properties.info_OTH1});
	data.push({ party: "other2", votes: d.properties.info_OTH2});

	var filterdata = [];

	$.each(data, function(i){
		if (data[i].votes > 0)
			filterdata.push(data[i]);
	});

	filterdata.sort(function(a, b){
			return b.votes - a.votes ;
	});

	// better way of doing this?

	var width = 250,
		height = 250;
		radius = Math.min(width, height) / 2;

	var arc = d3.svg.arc()
		.outerRadius(radius - 10)
		.innerRadius(0);

	var pie = d3.layout.pie()
		.sort(null)
		.value(function (d) {
			return d.votes;
		});

	var svg = d3.select("#information-pie").append("svg")
		.attr("width", width)
		.attr("height", height)
		.append("g")
		.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

		var g = svg.selectAll(".arc")
			.data(pie(filterdata))
			.enter().append("g")
			.attr("class", "arc");

		g.append("path")
			.attr("d", arc)
			.attr("class", function(d, i){
					return filterdata[i].party;
				});

	// creates table with vote counts/percentages
	$.each(filterdata, function(i){
		$("#information-chart").append("
" +
			partylist[filterdata[i].party] + "	" + filterdata[i].votes +
			"	" + (100 * filterdata[i].votes/d.properties.info_votescast).toFixed(2) +  "%
")
	})

	}

// bottom of right - vote chart

function doStuff(data) {

	$.each(data, function(i){
		$("#totals table").append("
" + data[i].party + "	" + data[i].seats + "	" + (data[i].votes).toLocaleString() + "	" + data[i].votepercent +"
")
	})
};

function parseData(url, callBack) {
	Papa.parse(url, {
		download: true,
		header: true,
		dynamicTyping: true,
		complete: function(results) {
			callBack(results.data);
		}
	});
}

parseData("votetotals.csv", doStuff);

<commit_msg>fixed zoom<commit_after>//add to d3js prototype
d3.selection.prototype.moveToFront = function() {
							return this.each(function(){
							this.parentNode.appendChild(this);
						});
					};

// far left filter scripts
filterStates = [{party: "null"}, {majoritylow: NaN}, {majorityhigh: NaN}, {region: "null"}]

seatsAfterFilter = []

function filterMap(){

	var	party  = filterStates[0].party;
	var majoritylow = filterStates[1].majoritylow;
	var majorityhigh = filterStates[2].majorityhigh;
	var region = filterStates[3].region;

	if (isNaN(majoritylow))
		majoritylow = 0
	if (isNaN(majorityhigh))
		majorityhigh = 1000000

	seatsAfterFilter = [];

	d3.json("map.json", function(uk){

		if (party == "null" && majority == "null" && majoritylow == NaN && majorityhigh == NaN)
			g.selectAll(".map")
				.attr("style", "opacity:1")

		else
			g.selectAll(".map")
				.attr("id", "filtertime")

			if (party == "null")
				g.selectAll("#filtertime")
					.attr("id", "partyfiltered")
			else
				g.selectAll("#filtertime")
					.attr("style", function(d){
						if (party != d.properties.incumbent)
							return "opacity: 0.1";
						})
					.attr("id", function(d){
						if (party == d.properties.incumbent)
							return "partyfiltered"
						});

			g.selectAll("#partyfiltered")
				.attr("style", function(d) {
					if (d.properties.info_majorityvotes < majoritylow || d.properties.info_majorityvotes > majorityhigh )
						return "opacity: 0.1"
					})
				.attr("id", function(d) {
					if (d.properties.info_majorityvotes >= majoritylow && d.properties.info_majorityvotes <=majorityhigh )
						return "majorityfiltered";
					});

			if (region == "null")
				g.selectAll("#majorityfiltered")
					.attr("id", function(d){
							seatsAfterFilter.push(d)

						})
			else
				g.selectAll("#majorityfiltered")
					.attr("style", function(d){
						if (region != d.properties.region)
							return "opacity: 0.1";
					})
					.attr("id", function(d){
						if (region == d.properties.region)
							seatsAfterFilter.push(d);
					});

			g.selectAll(".map")
				.attr("id", function(d) {
					return "i" + d.properties.info_id
				});
			$("#totalfilteredseats").html(" ");
			$("#filteredlisttable").html(" ");

		});
	}

function resetFilter(){

	filterStates[0].party = "null"
	filterStates[1].majoritylow = NaN
	filterStates[2].majorityhigh = NaN
	filterStates[3].region = "null"
	filterMap();

	$("#dropdownparty option:eq(0)").prop("selected", true);
	$("#majority").get(0).reset()
	$("#dropdownregion option:eq(0)").prop("selected", true);

	$("#totalfilteredseats").html(" ");
	$("#filteredlisttable").html(" ");
}

function generateSeatList(){
			$("#totalfilteredseats").html(" ");
			$("#filteredlisttable").html(" ");

			$("#totalfilteredseats").append("
Total : " + seatsAfterFilter.length + "
");
			$.each(seatsAfterFilter, function(i){
				$("#filteredlisttable").append("
" + seatsAfterFilter[i].properties.name + "
")

			});

		}

function zoomToClickedFilteredSeat(d){
	var id = "#i" + d.properties.info_id

	// redo this at some point so not just repeating code.

	previous = d3.select(previousnode)
	current = d3.select(id);
	repeat();

	function repeat(){
		previous.transition()
			.attr("opacity", 1)

		current.transition()
			.duration(1500)
			.attr("opacity", 1)
		.transition()
			.duration(1500)
			.attr("opacity", 0.2)
		.each("end", repeat);
		}

	var bounds = path.bounds(d),
		dx = Math.pow((bounds[1][0] - bounds[0][0]), 0.5),
		dy = Math.pow((bounds[1][1] - bounds[0][1]), 0.5),
		x = (bounds[0][0] + bounds[1][0]) / 2,
		y = (bounds[0][1] + bounds[1][1]) / 2,
		scale = .2 / Math.max(dx / width, dy / height * 2),
		translate = [width / 2 - scale * x, height / 2 - scale * y];

	svg.transition()
		.duration(2500)
		.call(zoom.translate(translate).scale(scale).event);

	seatinfo(d);
	previousnode = id;
	}

// scripts for zoom/pan/clicked

function clicked(d) {

	previous = d3.select(previousnode)
	current = d3.select(this);
	repeat();

	function repeat(){
		previous.transition()
			.attr("opacity", 1)

		current.transition()
			.duration(1500)
			.attr("opacity", 1)
		.transition()
			.duration(1500)
			.attr("opacity", 0.2)
		.each("end", repeat);
		}

	var bounds = path.bounds(d),
		dx = Math.pow((bounds[1][0] - bounds[0][0]), 0.5),
		dy = Math.pow((bounds[1][1] - bounds[0][1]), 0.5),
		x = (bounds[0][0] + bounds[1][0]) / 2,
		y = (bounds[0][1] + bounds[1][1]) / 2,

		scale = .025 / Math.max(dx /  width,  dy / height),
		translate = [width / 2 - scale * x, height / 2 - scale * y];

	svg.transition()
		.duration(2500)
		.call(zoom.translate(translate).scale(scale).event);

	seatinfo(d);
	previousnode = this;

}

function reset() {

	svg.transition()
		.duration(2500)
		.call(zoom.translate([0, 0]).scale(1).event);

}

function zoomed() {
	g.style("stroke-width", 1.5 / d3.event.scale + "px");
	g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");

}

function stopped() {
	if (d3.event.defaultPrevented) d3.event.stopPropagation();
}

// seatinfo on right

var oldclass = null;

function seatinfo(d){

	$("#information").removeClass(oldclass);
	$("#information").addClass(d.properties.incumbent).css("opacity", 0.8);
	$("#information-seatname").html("Seat	 " + d.properties.name +
		"	" + regionlist[d.properties.region] + "	");
	if (d.properties.info_bielection == "yes")
		$("#information-byelection").html("*");
	$("#information-party").html("Party	" + partylist[d.properties.incumbent] + "	");
	$("#information-mp").html("MP	" + d.properties.info_mpfirstname + " " + d.properties.info_mplastname + "	");
	$("#information-majority").html("Majority	 " + d.properties.info_majorityvotes  + "  =  " + d.properties.info_majoritypercent + "%	");
	$("#information-electorate").html("Turnout 	" + d.properties.info_votescast + " = " + d.properties.info_turnout +
		"%	Electorate: " + d.properties.info_electorate + "	");
	$("#information-pie").html(piechart(d));

	oldclass = d.properties.incumbent;
}

function piechart(d){

	$("#information-pie").empty();
	$("#information-chart").empty();

	$("#information-chart").html("

");

	var data = [];
	data.push({ party: "labour", votes: d.properties.info_LAB});
	data.push({ party: "conservative", votes: d.properties.info_CON});
	data.push({ party: "libdems", votes: d.properties.info_LIB});
	data.push({ party: "ukip", votes: d.properties.info_UKIP});
	data.push({ party: "snp", votes: d.properties.info_SNP});
	data.push({ party: "plaidcymru", votes: d.properties.info_PC});
	data.push({ party: "green", votes: d.properties.info_GRN});
	data.push({ party: "other1", votes: d.properties.info_OTH1});
	data.push({ party: "other2", votes: d.properties.info_OTH2});

	var filterdata = [];

	$.each(data, function(i){
		if (data[i].votes > 0)
			filterdata.push(data[i]);
	});

	filterdata.sort(function(a, b){
			return b.votes - a.votes ;
	});

	// better way of doing this?

	var width = 250,
		height = 250;
		radius = Math.min(width, height) / 2;

	var arc = d3.svg.arc()
		.outerRadius(radius - 10)
		.innerRadius(0);

	var pie = d3.layout.pie()
		.sort(null)
		.value(function (d) {
			return d.votes;
		});

	var svg = d3.select("#information-pie").append("svg")
		.attr("width", width)
		.attr("height", height)
		.append("g")
		.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

		var g = svg.selectAll(".arc")
			.data(pie(filterdata))
			.enter().append("g")
			.attr("class", "arc");

		g.append("path")
			.attr("d", arc)
			.attr("class", function(d, i){
					return filterdata[i].party;
				});

	// creates table with vote counts/percentages
	$.each(filterdata, function(i){
		$("#information-chart").append("
" +
			partylist[filterdata[i].party] + "	" + filterdata[i].votes +
			"	" + (100 * filterdata[i].votes/d.properties.info_votescast).toFixed(2) +  "%
")
	})

	}

// bottom of right - vote chart

function doStuff(data) {

	$.each(data, function(i){
		$("#totals table").append("
" + data[i].party + "	" + data[i].seats + "	" + (data[i].votes).toLocaleString() + "	" + data[i].votepercent +"
")
	})
};

function parseData(url, callBack) {
	Papa.parse(url, {
		download: true,
		header: true,
		dynamicTyping: true,
		complete: function(results) {
			callBack(results.data);
		}
	});
}

parseData("votetotals.csv", doStuff);

<|endoftext|>


<commit_before>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2017 Skyscanner Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import BpkButton from './src/BpkButton';
import {
  primaryThemeAttributes,
  secondaryThemeAttributes,
  linkThemeAttributes,
} from './src/themeAttributes';

export {
  primaryThemeAttributes,
  secondaryThemeAttributes,
  linkThemeAttributes,
};
export default BpkButton;
<commit_msg>[BPK-978] Fix unused import / export<commit_after>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2017 Skyscanner Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import BpkButton from './src/BpkButton';
import {
  primaryThemeAttributes,
  secondaryThemeAttributes,
} from './src/themeAttributes';

export {
  primaryThemeAttributes,
  secondaryThemeAttributes,
};
export default BpkButton;
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import cn from 'classnames'

import { accessor } from '../../utils/propTypes'
import EventWrapper from './EventWrapper'
import EventContainerWrapper from './EventContainerWrapper'
import WeekWrapper from './WeekWrapper'
import { mergeComponents } from './common'

/**
 * Creates a higher-order component (HOC) supporting drag & drop and optionally resizing
 * of events:
 *
 * ```js
 *    import Calendar from 'react-big-calendar'
 *    import withDragAndDrop from 'react-big-calendar/lib/addons/dragAndDrop'
 *    export default withDragAndDrop(Calendar)
 * ```
 *
 * Set `resizable` to true in your calendar if you want events to be resizable.
 *
 * The HOC adds `onEventDrop`, `onEventResize`, and `onDragStart` callback properties if the events are
 * moved or resized. These callbacks are called with these signatures:
 *
 * ```js
 *    function onEventDrop({ event, start, end, allDay }) {...}
 *    function onEventResize(type, { event, start, end, allDay }) {...}  // type is always 'drop'
 *    function onDragStart({ event, action, direction }) {...}
 * ```
 *
 * Moving and resizing of events has some subtlety which one should be aware of.
 *
 * In some situations, non-allDay events are displayed in "row" format where they
 * are rendered horizontally. This is the case for ALL events in a month view. It
 * is also occurs with multi-day events in a day or week view (unless `showMultiDayTimes`
 * is set).
 *
 * When dropping or resizing non-allDay events into a the header area or when
 * resizing them horizontally because they are displayed in row format, their
 * times are preserved, only their date is changed.
 *
 * If you care about these corner cases, you can examine the `allDay` param suppled
 * in the callback to determine how the user dropped or resized the event.
 *
 * Additionally, this HOC adds the callback props `onDropFromOutside` and `onDragOver`.
 * By default, the calendar will not respond to outside draggable items being dropped
 * onto it. However, if `onDropFromOutside` callback is passed, then when draggable
 * DOM elements are dropped on the calendar, the callback will fire, receiving an
 * object with start and end times, and an allDay boolean.
 *
 * If `onDropFromOutside` is passed, but `onDragOver` is not, any draggable event will be
 * droppable  onto the calendar by default. On the other hand, if an `onDragOver` callback
 * *is* passed, then it can discriminate as to whether a draggable item is droppable on the
 * calendar. To designate a draggable item as droppable, call `event.preventDefault`
 * inside `onDragOver`. If `event.preventDefault` is not called in the `onDragOver`
 * callback, then the draggable item will not be droppable on the calendar.
 *
 * * ```js
 *    function onDropFromOutside({ start, end, allDay }) {...}
 *    function onDragOver(DragEvent: event) {...}
 * ```
 * @param {*} Calendar
 * @param {*} backend
 */
export default function withDragAndDrop(Calendar) {
  class DragAndDropCalendar extends React.Component {
    static propTypes = {
      onEventDrop: PropTypes.func,
      onEventResize: PropTypes.func,
      onDragStart: PropTypes.func,
      onDragOver: PropTypes.func,
      onDropFromOutside: PropTypes.func,

      dragFromOutsideItem: PropTypes.func,

      draggableAccessor: accessor,
      resizableAccessor: accessor,

      selectable: PropTypes.oneOf([true, false, 'ignoreEvents']),
      resizable: PropTypes.bool,
      components: PropTypes.object,
      elementProps: PropTypes.object,
      step: PropTypes.number,
    }

    static defaultProps = {
      // TODO: pick these up from Calendar.defaultProps
      components: {},
      draggableAccessor: null,
      resizableAccessor: null,
      step: 30,
    }

    static contextTypes = {
      dragDropManager: PropTypes.object,
    }

    static childContextTypes = {
      draggable: PropTypes.shape({
        onStart: PropTypes.func,
        onEnd: PropTypes.func,
        onBeginAction: PropTypes.func,
        onDropFromOutside: PropTypes.fun,
        dragFromOutsideItem: PropTypes.fun,
        draggableAccessor: accessor,
        resizableAccessor: accessor,
        dragAndDropAction: PropTypes.object,
      }),
    }

    constructor(...args) {
      super(...args)

      const { components } = this.props

      this.components = mergeComponents(components, {
        eventWrapper: EventWrapper,
        eventContainerWrapper: EventContainerWrapper,
        weekWrapper: WeekWrapper,
      })

      this.state = { interacting: false }
    }

    getChildContext() {
      return {
        draggable: {
          onStart: this.handleInteractionStart,
          onEnd: this.handleInteractionEnd,
          onBeginAction: this.handleBeginAction,
          onDropFromOutside: this.props.onDropFromOutside,
          dragFromOutsideItem: this.props.dragFromOutsideItem,
          draggableAccessor: this.props.draggableAccessor,
          resizableAccessor: this.props.resizableAccessor,
          dragAndDropAction: this.state,
        },
      }
    }

    defaultOnDragOver = event => {
      event.preventDefault()
    }

    handleBeginAction = (event, action, direction) => {
      const { onDragStart } = this.props
      this.setState({ event, action, direction })
      if (onDragStart) {
        onDragStart({ event, action, direction })
      }
    }

    handleInteractionStart = () => {
      if (this.state.interacting === false) this.setState({ interacting: true })
    }

    handleInteractionEnd = interactionInfo => {
      const { action, event } = this.state

      if (!action) return

      this.setState({
        action: null,
        event: null,
        interacting: false,
        direction: null,
      })

      if (interactionInfo == null) return

      interactionInfo.event = event
      if (action === 'move') this.props.onEventDrop(interactionInfo)
      if (action === 'resize') this.props.onEventResize(interactionInfo)
    }

    render() {
      const { selectable, elementProps, ...props } = this.props
      const { interacting } = this.state
      delete props.onEventDrop
      delete props.onEventResize

      props.selectable = selectable ? 'ignoreEvents' : false

      const elementPropsWithDropFromOutside = this.props.onDropFromOutside
        ? {
            ...elementProps,
            onDragOver: this.props.onDragOver || this.defaultOnDragOver,
          }
        : elementProps

      props.className = cn(
        props.className,
        'rbc-addons-dnd',
        !!interacting && 'rbc-addons-dnd-is-dragging'
      )

      return (
        <Calendar
          {...props}
          elementProps={elementPropsWithDropFromOutside}
          components={this.components}
        />
      )
    }
  }

  return DragAndDropCalendar
}
<commit_msg>fix: invalid prop-types. (#1435)<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import cn from 'classnames'

import { accessor } from '../../utils/propTypes'
import EventWrapper from './EventWrapper'
import EventContainerWrapper from './EventContainerWrapper'
import WeekWrapper from './WeekWrapper'
import { mergeComponents } from './common'

/**
 * Creates a higher-order component (HOC) supporting drag & drop and optionally resizing
 * of events:
 *
 * ```js
 *    import Calendar from 'react-big-calendar'
 *    import withDragAndDrop from 'react-big-calendar/lib/addons/dragAndDrop'
 *    export default withDragAndDrop(Calendar)
 * ```
 *
 * Set `resizable` to true in your calendar if you want events to be resizable.
 *
 * The HOC adds `onEventDrop`, `onEventResize`, and `onDragStart` callback properties if the events are
 * moved or resized. These callbacks are called with these signatures:
 *
 * ```js
 *    function onEventDrop({ event, start, end, allDay }) {...}
 *    function onEventResize(type, { event, start, end, allDay }) {...}  // type is always 'drop'
 *    function onDragStart({ event, action, direction }) {...}
 * ```
 *
 * Moving and resizing of events has some subtlety which one should be aware of.
 *
 * In some situations, non-allDay events are displayed in "row" format where they
 * are rendered horizontally. This is the case for ALL events in a month view. It
 * is also occurs with multi-day events in a day or week view (unless `showMultiDayTimes`
 * is set).
 *
 * When dropping or resizing non-allDay events into a the header area or when
 * resizing them horizontally because they are displayed in row format, their
 * times are preserved, only their date is changed.
 *
 * If you care about these corner cases, you can examine the `allDay` param suppled
 * in the callback to determine how the user dropped or resized the event.
 *
 * Additionally, this HOC adds the callback props `onDropFromOutside` and `onDragOver`.
 * By default, the calendar will not respond to outside draggable items being dropped
 * onto it. However, if `onDropFromOutside` callback is passed, then when draggable
 * DOM elements are dropped on the calendar, the callback will fire, receiving an
 * object with start and end times, and an allDay boolean.
 *
 * If `onDropFromOutside` is passed, but `onDragOver` is not, any draggable event will be
 * droppable  onto the calendar by default. On the other hand, if an `onDragOver` callback
 * *is* passed, then it can discriminate as to whether a draggable item is droppable on the
 * calendar. To designate a draggable item as droppable, call `event.preventDefault`
 * inside `onDragOver`. If `event.preventDefault` is not called in the `onDragOver`
 * callback, then the draggable item will not be droppable on the calendar.
 *
 * * ```js
 *    function onDropFromOutside({ start, end, allDay }) {...}
 *    function onDragOver(DragEvent: event) {...}
 * ```
 * @param {*} Calendar
 * @param {*} backend
 */
export default function withDragAndDrop(Calendar) {
  class DragAndDropCalendar extends React.Component {
    static propTypes = {
      onEventDrop: PropTypes.func,
      onEventResize: PropTypes.func,
      onDragStart: PropTypes.func,
      onDragOver: PropTypes.func,
      onDropFromOutside: PropTypes.func,

      dragFromOutsideItem: PropTypes.func,

      draggableAccessor: accessor,
      resizableAccessor: accessor,

      selectable: PropTypes.oneOf([true, false, 'ignoreEvents']),
      resizable: PropTypes.bool,
      components: PropTypes.object,
      elementProps: PropTypes.object,
      step: PropTypes.number,
    }

    static defaultProps = {
      // TODO: pick these up from Calendar.defaultProps
      components: {},
      draggableAccessor: null,
      resizableAccessor: null,
      step: 30,
    }

    static contextTypes = {
      dragDropManager: PropTypes.object,
    }

    static childContextTypes = {
      draggable: PropTypes.shape({
        onStart: PropTypes.func,
        onEnd: PropTypes.func,
        onBeginAction: PropTypes.func,
        onDropFromOutside: PropTypes.func,
        dragFromOutsideItem: PropTypes.func,
        draggableAccessor: accessor,
        resizableAccessor: accessor,
        dragAndDropAction: PropTypes.object,
      }),
    }

    constructor(...args) {
      super(...args)

      const { components } = this.props

      this.components = mergeComponents(components, {
        eventWrapper: EventWrapper,
        eventContainerWrapper: EventContainerWrapper,
        weekWrapper: WeekWrapper,
      })

      this.state = { interacting: false }
    }

    getChildContext() {
      return {
        draggable: {
          onStart: this.handleInteractionStart,
          onEnd: this.handleInteractionEnd,
          onBeginAction: this.handleBeginAction,
          onDropFromOutside: this.props.onDropFromOutside,
          dragFromOutsideItem: this.props.dragFromOutsideItem,
          draggableAccessor: this.props.draggableAccessor,
          resizableAccessor: this.props.resizableAccessor,
          dragAndDropAction: this.state,
        },
      }
    }

    defaultOnDragOver = event => {
      event.preventDefault()
    }

    handleBeginAction = (event, action, direction) => {
      const { onDragStart } = this.props
      this.setState({ event, action, direction })
      if (onDragStart) {
        onDragStart({ event, action, direction })
      }
    }

    handleInteractionStart = () => {
      if (this.state.interacting === false) this.setState({ interacting: true })
    }

    handleInteractionEnd = interactionInfo => {
      const { action, event } = this.state

      if (!action) return

      this.setState({
        action: null,
        event: null,
        interacting: false,
        direction: null,
      })

      if (interactionInfo == null) return

      interactionInfo.event = event
      if (action === 'move') this.props.onEventDrop(interactionInfo)
      if (action === 'resize') this.props.onEventResize(interactionInfo)
    }

    render() {
      const { selectable, elementProps, ...props } = this.props
      const { interacting } = this.state
      delete props.onEventDrop
      delete props.onEventResize

      props.selectable = selectable ? 'ignoreEvents' : false

      const elementPropsWithDropFromOutside = this.props.onDropFromOutside
        ? {
            ...elementProps,
            onDragOver: this.props.onDragOver || this.defaultOnDragOver,
          }
        : elementProps

      props.className = cn(
        props.className,
        'rbc-addons-dnd',
        !!interacting && 'rbc-addons-dnd-is-dragging'
      )

      return (
        <Calendar
          {...props}
          elementProps={elementPropsWithDropFromOutside}
          components={this.components}
        />
      )
    }
  }

  return DragAndDropCalendar
}
<|endoftext|>