<commit_before>'use strict';

const WebViewImpl = require('./web-view');
const guestViewInternal = require('./guest-view-internal');
const webViewConstants = require('./web-view-constants');
const remote = require('electron').remote;

// Helper function to resolve url set in attribute.
var a = document.createElement('a');

var resolveURL = function(url) {
  a.href = url;
  return a.href;
};

// Attribute objects.
// Default implementation of a WebView attribute.
class WebViewAttribute {
  constructor(name, webViewImpl) {
    this.name = name;
    this.value = webViewImpl.webviewNode[name] || '';
    this.webViewImpl = webViewImpl;
    this.ignoreMutation = false;
    this.defineProperty();
  }

  // Retrieves and returns the attribute's value.
  getValue() {
    return this.webViewImpl.webviewNode.getAttribute(this.name) || this.value;
  }

  // Sets the attribute's value.
  setValue(value) {
    return this.webViewImpl.webviewNode.setAttribute(this.name, value || '');
  }

  // Changes the attribute's value without triggering its mutation handler.
  setValueIgnoreMutation(value) {
    this.ignoreMutation = true;
    this.setValue(value);
    return this.ignoreMutation = false;
  }

  // Defines this attribute as a property on the webview node.
  defineProperty() {
    return Object.defineProperty(this.webViewImpl.webviewNode, this.name, {
      get: (function(_this) {
        return function() {
          return _this.getValue();
        };
      })(this),
      set: (function(_this) {
        return function(value) {
          return _this.setValue(value);
        };
      })(this),
      enumerable: true
    });
  };

  // Called when the attribute's value changes.
  handleMutation() {}
}

// An attribute that is treated as a Boolean.
class BooleanAttribute extends WebViewAttribute {
  constructor(name, webViewImpl) {
    super(name, webViewImpl);
  }

  getValue() {
    return this.webViewImpl.webviewNode.hasAttribute(this.name);
  }

  setValue(value) {
    if (!value) {
      return this.webViewImpl.webviewNode.removeAttribute(this.name);
    } else {
      return this.webViewImpl.webviewNode.setAttribute(this.name, '');
    }
  }
}

// Attribute that specifies whether transparency is allowed in the webview.
class AllowTransparencyAttribute extends BooleanAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, webViewImpl);
  }

  handleMutation(oldValue, newValue) {
    if (!this.webViewImpl.guestInstanceId) {
      return;
    }
    return guestViewInternal.setAllowTransparency(this.webViewImpl.guestInstanceId, this.getValue());
  }
}

// Attribute used to define the demension limits of autosizing.
class AutosizeDimensionAttribute extends WebViewAttribute {
  constructor(name, webViewImpl) {
    super(name, webViewImpl);
  }

  getValue() {
    return parseInt(this.webViewImpl.webviewNode.getAttribute(this.name)) || 0;
  }

  handleMutation(oldValue, newValue) {
    if (!this.webViewImpl.guestInstanceId) {
      return;
    }
    return guestViewInternal.setSize(this.webViewImpl.guestInstanceId, {
      enableAutoSize: this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue(),
      min: {
        width: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0),
        height: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0)
      },
      max: {
        width: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0),
        height: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0)
      }
    });
  }
}

// Attribute that specifies whether the webview should be autosized.
class AutosizeAttribute extends BooleanAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_AUTOSIZE, webViewImpl);
  }
}

AutosizeAttribute.prototype.handleMutation = AutosizeDimensionAttribute.prototype.handleMutation;

// Attribute representing the state of the storage partition.
class PartitionAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_PARTITION, webViewImpl);
    this.validPartitionId = true;
  }

  handleMutation(oldValue, newValue) {
    newValue = newValue || '';

    // The partition cannot change if the webview has already navigated.
    if (!this.webViewImpl.beforeFirstNavigation) {
      window.console.error(webViewConstants.ERROR_MSG_ALREADY_NAVIGATED);
      this.setValueIgnoreMutation(oldValue);
      return;
    }
    if (newValue === 'persist:') {
      this.validPartitionId = false;
      return window.console.error(webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE);
    }
  }
}

// Attribute that handles the location and navigation of the webview.
class SrcAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_SRC, webViewImpl);
    this.setupMutationObserver();
  }

  getValue() {
    if (this.webViewImpl.webviewNode.hasAttribute(this.name)) {
      return resolveURL(this.webViewImpl.webviewNode.getAttribute(this.name));
    } else {
      return this.value;
    }
  }

  setValueIgnoreMutation(value) {
    super.setValueIgnoreMutation(value);

    // takeRecords() is needed to clear queued up src mutations. Without it, it
    // is possible for this change to get picked up asyncronously by src's
    // mutation observer |observer|, and then get handled even though we do not
    // want to handle this mutation.
    return this.observer.takeRecords();
  }

  handleMutation(oldValue, newValue) {

    // Once we have navigated, we don't allow clearing the src attribute.
    // Once <webview> enters a navigated state, it cannot return to a
    // placeholder state.
    if (!newValue && oldValue) {

      // src attribute changes normally initiate a navigation. We suppress
      // the next src attribute handler call to avoid reloading the page
      // on every guest-initiated navigation.
      this.setValueIgnoreMutation(oldValue);
      return;
    }
    return this.parse();
  }

  // The purpose of this mutation observer is to catch assignment to the src
  // attribute without any changes to its value. This is useful in the case
  // where the webview guest has crashed and navigating to the same address
  // spawns off a new process.
  setupMutationObserver() {
    var params;
    this.observer = new MutationObserver((function(_this) {
      return function(mutations) {
        var i, len, mutation, newValue, oldValue;
        for (i = 0, len = mutations.length; i < len; i++) {
          mutation = mutations[i];
          oldValue = mutation.oldValue;
          newValue = _this.getValue();
          if (oldValue !== newValue) {
            return;
          }
          _this.handleMutation(oldValue, newValue);
        }
      };
    })(this));
    params = {
      attributes: true,
      attributeOldValue: true,
      attributeFilter: [this.name]
    };
    return this.observer.observe(this.webViewImpl.webviewNode, params);
  }

  parse() {
    var guestContents, httpreferrer, opts, useragent;
    if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId || !this.getValue()) {
      return;
    }
    if (this.webViewImpl.guestInstanceId == null) {
      if (this.webViewImpl.beforeFirstNavigation) {
        this.webViewImpl.beforeFirstNavigation = false;
        this.webViewImpl.createGuest();
      }
      return;
    }

    // Navigate to |this.src|.
    opts = {};
    httpreferrer = this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue();
    if (httpreferrer) {
      opts.httpReferrer = httpreferrer;
    }
    useragent = this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_USERAGENT].getValue();
    if (useragent) {
      opts.userAgent = useragent;
    }
    guestContents = remote.getGuestWebContents(this.webViewImpl.guestInstanceId);
    return guestContents.loadURL(this.getValue(), opts);
  }
}

// Attribute specifies HTTP referrer.
class HttpReferrerAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_HTTPREFERRER, webViewImpl);
  }
}

// Attribute specifies user agent
class UserAgentAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_USERAGENT, webViewImpl);
  }
}

// Attribute that set preload script.
class PreloadAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_PRELOAD, webViewImpl);
  }

  getValue() {
    var preload, protocol;
    if (!this.webViewImpl.webviewNode.hasAttribute(this.name)) {
      return this.value;
    }
    preload = resolveURL(this.webViewImpl.webviewNode.getAttribute(this.name));
    protocol = preload.substr(0, 5);
    if (protocol !== 'file:') {
      console.error(webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE);
      preload = '';
    }
    return preload;
  }
}

// Sets up all of the webview attributes.
WebViewImpl.prototype.setupWebViewAttributes = function() {
  var attribute, autosizeAttributes, i, len, results;
  this.attributes = {};
  this.attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] = new AllowTransparencyAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE] = new AutosizeAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_PARTITION] = new PartitionAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_SRC] = new SrcAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER] = new HttpReferrerAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_USERAGENT] = new UserAgentAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_NODEINTEGRATION] = new BooleanAttribute(webViewConstants.ATTRIBUTE_NODEINTEGRATION, this);
  this.attributes[webViewConstants.ATTRIBUTE_PLUGINS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_PLUGINS, this);
  this.attributes[webViewConstants.ATTRIBUTE_DISABLEWEBSECURITY] = new BooleanAttribute(webViewConstants.ATTRIBUTE_DISABLEWEBSECURITY, this);
  this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this);
  this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this);
  autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH];
  results = [];
  for (i = 0, len = autosizeAttributes.length; i < len; i++) {
    attribute = autosizeAttributes[i];
    results.push(this.attributes[attribute] = new AutosizeDimensionAttribute(attribute, this));
  }
  return results;
};
<commit_msg>Remove unneeded semicolon<commit_after>'use strict';

const WebViewImpl = require('./web-view');
const guestViewInternal = require('./guest-view-internal');
const webViewConstants = require('./web-view-constants');
const remote = require('electron').remote;

// Helper function to resolve url set in attribute.
var a = document.createElement('a');

var resolveURL = function(url) {
  a.href = url;
  return a.href;
};

// Attribute objects.
// Default implementation of a WebView attribute.
class WebViewAttribute {
  constructor(name, webViewImpl) {
    this.name = name;
    this.value = webViewImpl.webviewNode[name] || '';
    this.webViewImpl = webViewImpl;
    this.ignoreMutation = false;
    this.defineProperty();
  }

  // Retrieves and returns the attribute's value.
  getValue() {
    return this.webViewImpl.webviewNode.getAttribute(this.name) || this.value;
  }

  // Sets the attribute's value.
  setValue(value) {
    return this.webViewImpl.webviewNode.setAttribute(this.name, value || '');
  }

  // Changes the attribute's value without triggering its mutation handler.
  setValueIgnoreMutation(value) {
    this.ignoreMutation = true;
    this.setValue(value);
    return this.ignoreMutation = false;
  }

  // Defines this attribute as a property on the webview node.
  defineProperty() {
    return Object.defineProperty(this.webViewImpl.webviewNode, this.name, {
      get: (function(_this) {
        return function() {
          return _this.getValue();
        };
      })(this),
      set: (function(_this) {
        return function(value) {
          return _this.setValue(value);
        };
      })(this),
      enumerable: true
    });
  }

  // Called when the attribute's value changes.
  handleMutation() {}
}

// An attribute that is treated as a Boolean.
class BooleanAttribute extends WebViewAttribute {
  constructor(name, webViewImpl) {
    super(name, webViewImpl);
  }

  getValue() {
    return this.webViewImpl.webviewNode.hasAttribute(this.name);
  }

  setValue(value) {
    if (!value) {
      return this.webViewImpl.webviewNode.removeAttribute(this.name);
    } else {
      return this.webViewImpl.webviewNode.setAttribute(this.name, '');
    }
  }
}

// Attribute that specifies whether transparency is allowed in the webview.
class AllowTransparencyAttribute extends BooleanAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, webViewImpl);
  }

  handleMutation(oldValue, newValue) {
    if (!this.webViewImpl.guestInstanceId) {
      return;
    }
    return guestViewInternal.setAllowTransparency(this.webViewImpl.guestInstanceId, this.getValue());
  }
}

// Attribute used to define the demension limits of autosizing.
class AutosizeDimensionAttribute extends WebViewAttribute {
  constructor(name, webViewImpl) {
    super(name, webViewImpl);
  }

  getValue() {
    return parseInt(this.webViewImpl.webviewNode.getAttribute(this.name)) || 0;
  }

  handleMutation(oldValue, newValue) {
    if (!this.webViewImpl.guestInstanceId) {
      return;
    }
    return guestViewInternal.setSize(this.webViewImpl.guestInstanceId, {
      enableAutoSize: this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue(),
      min: {
        width: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0),
        height: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0)
      },
      max: {
        width: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0),
        height: parseInt(this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0)
      }
    });
  }
}

// Attribute that specifies whether the webview should be autosized.
class AutosizeAttribute extends BooleanAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_AUTOSIZE, webViewImpl);
  }
}

AutosizeAttribute.prototype.handleMutation = AutosizeDimensionAttribute.prototype.handleMutation;

// Attribute representing the state of the storage partition.
class PartitionAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_PARTITION, webViewImpl);
    this.validPartitionId = true;
  }

  handleMutation(oldValue, newValue) {
    newValue = newValue || '';

    // The partition cannot change if the webview has already navigated.
    if (!this.webViewImpl.beforeFirstNavigation) {
      window.console.error(webViewConstants.ERROR_MSG_ALREADY_NAVIGATED);
      this.setValueIgnoreMutation(oldValue);
      return;
    }
    if (newValue === 'persist:') {
      this.validPartitionId = false;
      return window.console.error(webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE);
    }
  }
}

// Attribute that handles the location and navigation of the webview.
class SrcAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_SRC, webViewImpl);
    this.setupMutationObserver();
  }

  getValue() {
    if (this.webViewImpl.webviewNode.hasAttribute(this.name)) {
      return resolveURL(this.webViewImpl.webviewNode.getAttribute(this.name));
    } else {
      return this.value;
    }
  }

  setValueIgnoreMutation(value) {
    super.setValueIgnoreMutation(value);

    // takeRecords() is needed to clear queued up src mutations. Without it, it
    // is possible for this change to get picked up asyncronously by src's
    // mutation observer |observer|, and then get handled even though we do not
    // want to handle this mutation.
    return this.observer.takeRecords();
  }

  handleMutation(oldValue, newValue) {

    // Once we have navigated, we don't allow clearing the src attribute.
    // Once <webview> enters a navigated state, it cannot return to a
    // placeholder state.
    if (!newValue && oldValue) {

      // src attribute changes normally initiate a navigation. We suppress
      // the next src attribute handler call to avoid reloading the page
      // on every guest-initiated navigation.
      this.setValueIgnoreMutation(oldValue);
      return;
    }
    return this.parse();
  }

  // The purpose of this mutation observer is to catch assignment to the src
  // attribute without any changes to its value. This is useful in the case
  // where the webview guest has crashed and navigating to the same address
  // spawns off a new process.
  setupMutationObserver() {
    var params;
    this.observer = new MutationObserver((function(_this) {
      return function(mutations) {
        var i, len, mutation, newValue, oldValue;
        for (i = 0, len = mutations.length; i < len; i++) {
          mutation = mutations[i];
          oldValue = mutation.oldValue;
          newValue = _this.getValue();
          if (oldValue !== newValue) {
            return;
          }
          _this.handleMutation(oldValue, newValue);
        }
      };
    })(this));
    params = {
      attributes: true,
      attributeOldValue: true,
      attributeFilter: [this.name]
    };
    return this.observer.observe(this.webViewImpl.webviewNode, params);
  }

  parse() {
    var guestContents, httpreferrer, opts, useragent;
    if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId || !this.getValue()) {
      return;
    }
    if (this.webViewImpl.guestInstanceId == null) {
      if (this.webViewImpl.beforeFirstNavigation) {
        this.webViewImpl.beforeFirstNavigation = false;
        this.webViewImpl.createGuest();
      }
      return;
    }

    // Navigate to |this.src|.
    opts = {};
    httpreferrer = this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue();
    if (httpreferrer) {
      opts.httpReferrer = httpreferrer;
    }
    useragent = this.webViewImpl.attributes[webViewConstants.ATTRIBUTE_USERAGENT].getValue();
    if (useragent) {
      opts.userAgent = useragent;
    }
    guestContents = remote.getGuestWebContents(this.webViewImpl.guestInstanceId);
    return guestContents.loadURL(this.getValue(), opts);
  }
}

// Attribute specifies HTTP referrer.
class HttpReferrerAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_HTTPREFERRER, webViewImpl);
  }
}

// Attribute specifies user agent
class UserAgentAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_USERAGENT, webViewImpl);
  }
}

// Attribute that set preload script.
class PreloadAttribute extends WebViewAttribute {
  constructor(webViewImpl) {
    super(webViewConstants.ATTRIBUTE_PRELOAD, webViewImpl);
  }

  getValue() {
    var preload, protocol;
    if (!this.webViewImpl.webviewNode.hasAttribute(this.name)) {
      return this.value;
    }
    preload = resolveURL(this.webViewImpl.webviewNode.getAttribute(this.name));
    protocol = preload.substr(0, 5);
    if (protocol !== 'file:') {
      console.error(webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE);
      preload = '';
    }
    return preload;
  }
}

// Sets up all of the webview attributes.
WebViewImpl.prototype.setupWebViewAttributes = function() {
  var attribute, autosizeAttributes, i, len, results;
  this.attributes = {};
  this.attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] = new AllowTransparencyAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE] = new AutosizeAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_PARTITION] = new PartitionAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_SRC] = new SrcAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER] = new HttpReferrerAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_USERAGENT] = new UserAgentAttribute(this);
  this.attributes[webViewConstants.ATTRIBUTE_NODEINTEGRATION] = new BooleanAttribute(webViewConstants.ATTRIBUTE_NODEINTEGRATION, this);
  this.attributes[webViewConstants.ATTRIBUTE_PLUGINS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_PLUGINS, this);
  this.attributes[webViewConstants.ATTRIBUTE_DISABLEWEBSECURITY] = new BooleanAttribute(webViewConstants.ATTRIBUTE_DISABLEWEBSECURITY, this);
  this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this);
  this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this);
  autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH];
  results = [];
  for (i = 0, len = autosizeAttributes.length; i < len; i++) {
    attribute = autosizeAttributes[i];
    results.push(this.attributes[attribute] = new AutosizeDimensionAttribute(attribute, this));
  }
  return results;
};
<|endoftext|>


<commit_before>var analytics = require('analytics');
var d3 = require('d3');
var convert = require('convert');
var Feedback = require('feedback-modal');
var mouseenter = require('mouseenter');
var mouseleave = require('mouseleave');
var Calculator = require('route-cost-calculator');
var RouteDirections = require('route-directions-table');
var RouteModal = require('route-modal');
var routeSummarySegments = require('route-summary-segments');
var routeResource = require('route-resource');
var session = require('session');
//var transitive = require('transitive');
var view = require('view');
var showMapView = require('map-view');
/**
 * Expose `View`
 */

var View = module.exports = view(require('./template.html'), function(view, model) {
  mouseenter(view.el, function() {
      showMapView.cleanMarkerCollision();
      showMapView.drawItinerationMakerCollision(model.index);
      var itineration = JSON.parse(localStorage.getItem('itineration'));
      for (var i=0; i<itineration.length;i++) {
           var r3 = d3.selectAll(".iteration-"+i);
           if (i!=model.index){
                r3.transition().duration(600).style("stroke", "#E0E0E0");
                r3.attr("data-show","0");

              var rec2 = d3.selectAll(".circle-fade-"+i);
              rec2.attr('class', 'leaflet-marker-icon leaflet-div-icon2 circle-fade-'+i+ ' leaflet-zoom-hide');
           }else {
                r3.attr("data-show","1");
           }
      }

      var orden = 0;
      d3.selectAll(".iteration-200").each(function(e){
            var element = d3.select(this);
            var parent = d3.select(element.node().parentNode);
            parent.attr("class", "g-element");
            parent.attr("data-orden", orden.toString());
            if (Boolean(parseInt(element.attr("data-show")))) {
                parent.attr("data-show", "1");
            }else {
                parent.attr("data-show", "0");
            }

            orden++;
      });

      d3.selectAll(".g-element").each(function(a,b){
            if (Boolean(parseInt(d3.select(this).attr("data-show")))) {
                d3.select(this).node().parentNode.appendChild(this);
            }

      });
  });

  mouseleave(view.el, function() {

        var layer_ordenados = [];
        d3.selectAll(".g-element").each(function(a,b){
            var orden = parseInt(d3.select(this).attr("data-orden"));
            layer_ordenados[orden] = this;

        });

        for (i in layer_ordenados) {
            var element = d3.select(layer_ordenados[i]);
            var child = element.select("path");
            element.attr("data-show", "0");
            child.transition().duration(600).style("stroke",function(i,v){
                    return d3.select(this).attr("stroke");

            });
            child.attr("data-show", "0");
            element.node().parentNode.appendChild(layer_ordenados[i]);
        }
    /*
   showMapView.cleanPolyline();
   showMapView.cleanMarkerpoint();
   showMapView.cleanMarkerCollision();

    var sesion_plan = JSON.parse(localStorage.getItem('dataplan'));
    sesion_plan = sesion_plan.plan;

     var itineraries = sesion_plan.itineraries;
      for (var i= 0; i < itineraries.length; i++) {

          for (var j=0; j < itineraries[i].legs.length; j++) {
             showMapView.drawRouteAmigo(itineraries[i].legs[j], itineraries[i].legs[j].mode, i);
          }
      }
      showMapView.drawMakerCollision();
        */
  });
});

View.prototype.calculator = function() {
  return new Calculator(this.model);
};

View.prototype.directions = function() {
  return new RouteDirections(this.model);
};

View.prototype.segments = function() {
  return routeSummarySegments(this.model);
};

View.prototype.costSavings = function() {
  return convert.roundNumberToString(this.model.costSavings());
};

View.prototype.timeSavingsAndNoCostSavings = function() {
  return this.model.timeSavings() && !this.model.costSavings();
};

/**
 * Show/hide
 */

View.prototype.showDetails = function(e) {
  e.preventDefault();
  var el = this.el;
  var expanded = document.querySelector('.option.expanded');
  if (expanded) expanded.classList.remove('expanded');

  el.classList.add('expanded');

  analytics.track('Expanded Route Details', {
    plan: session.plan().generateQuery(),
    route: {
      modes: this.model.modes(),
      summary: this.model.summary()
    }
  });

  var scrollable = document.querySelector('.scrollable');
  scrollable.scrollTop = el.offsetTop - 52;
};

View.prototype.hideDetails = function(e) {
  e.preventDefault();
  var list = this.el.classList;
  if (list.contains('expanded')) {
    list.remove('expanded');
  }
};

/**
 * Get the option number for display purposes (1-based)
 */

View.prototype.optionNumber = function() {
  return this.model.index + 1;
};

/**
 * View
 */

View.prototype.feedback = function(e) {
  e.preventDefault();
  Feedback(this.model).show();
};

/**
 * Select this option
 */

View.prototype.selectOption = function() {
  var route = this.model;
  var plan = session.plan();
  var tags = route.tags(plan);

  analytics.send_ga({
    category: 'route-card',
    action: 'select route',
    label: JSON.stringify(tags),
    value: 1
  });
  routeResource.findByTags(tags, function(err, resources) {
    var routeModal = new RouteModal(route, null, {
      context: 'route-card',
      resources: resources
    });
    routeModal.show();
    routeModal.on('next', function() {
      routeModal.hide();
    });
  });
};
<commit_msg>ordena luego agrega<commit_after>var analytics = require('analytics');
var d3 = require('d3');
var convert = require('convert');
var Feedback = require('feedback-modal');
var mouseenter = require('mouseenter');
var mouseleave = require('mouseleave');
var Calculator = require('route-cost-calculator');
var RouteDirections = require('route-directions-table');
var RouteModal = require('route-modal');
var routeSummarySegments = require('route-summary-segments');
var routeResource = require('route-resource');
var session = require('session');
//var transitive = require('transitive');
var view = require('view');
var showMapView = require('map-view');
/**
 * Expose `View`
 */

var View = module.exports = view(require('./template.html'), function(view, model) {
  mouseenter(view.el, function() {
      showMapView.cleanMarkerCollision();
      showMapView.drawItinerationMakerCollision(model.index);
      var itineration = JSON.parse(localStorage.getItem('itineration'));
      for (var i=0; i<itineration.length;i++) {
           var r3 = d3.selectAll(".iteration-"+i);
           if (i!=model.index){
                r3.transition().duration(600).style("stroke", "#E0E0E0");
                r3.attr("data-show","0");

              var rec2 = d3.selectAll(".circle-fade-"+i);
              rec2.attr('class', 'leaflet-marker-icon leaflet-div-icon2 circle-fade-'+i+ ' leaflet-zoom-hide');
           }else {
                r3.attr("data-show","1");
           }
      }

      var orden = 0;
      d3.selectAll(".iteration-200").each(function(e){
            var element = d3.select(this);
            var parent = d3.select(element.node().parentNode);
            parent.attr("class", "g-element");
            parent.attr("data-orden", orden.toString());
            if (Boolean(parseInt(element.attr("data-show")))) {
                parent.attr("data-show", "1");
            }else {
                parent.attr("data-show", "0");
            }

            orden++;
      });

      d3.selectAll(".g-element").each(function(a,b){
            if (Boolean(parseInt(d3.select(this).attr("data-show")))) {
                d3.select(this).node().parentNode.appendChild(this);
            }

      });
  });

  mouseleave(view.el, function() {

        var layer_ordenados = [];
        d3.selectAll(".g-element").each(function(a,b){
            var orden = parseInt(d3.select(this).attr("data-orden"));
            layer_ordenados[orden] = this;

        });

        for (i in layer_ordenados) {
            var element = d3.select(layer_ordenados[i]);
            var child = element.select("path");
            element.attr("data-show", "0");

            element.node().parentNode.appendChild(layer_ordenados[i]);

            child.transition().duration(600).style("stroke",function(i,v){
                    return d3.select(this).attr("stroke");

            });
            child.attr("data-show", "0");

        }
    /*
   showMapView.cleanPolyline();
   showMapView.cleanMarkerpoint();
   showMapView.cleanMarkerCollision();

    var sesion_plan = JSON.parse(localStorage.getItem('dataplan'));
    sesion_plan = sesion_plan.plan;

     var itineraries = sesion_plan.itineraries;
      for (var i= 0; i < itineraries.length; i++) {

          for (var j=0; j < itineraries[i].legs.length; j++) {
             showMapView.drawRouteAmigo(itineraries[i].legs[j], itineraries[i].legs[j].mode, i);
          }
      }
      showMapView.drawMakerCollision();
        */
  });
});

View.prototype.calculator = function() {
  return new Calculator(this.model);
};

View.prototype.directions = function() {
  return new RouteDirections(this.model);
};

View.prototype.segments = function() {
  return routeSummarySegments(this.model);
};

View.prototype.costSavings = function() {
  return convert.roundNumberToString(this.model.costSavings());
};

View.prototype.timeSavingsAndNoCostSavings = function() {
  return this.model.timeSavings() && !this.model.costSavings();
};

/**
 * Show/hide
 */

View.prototype.showDetails = function(e) {
  e.preventDefault();
  var el = this.el;
  var expanded = document.querySelector('.option.expanded');
  if (expanded) expanded.classList.remove('expanded');

  el.classList.add('expanded');

  analytics.track('Expanded Route Details', {
    plan: session.plan().generateQuery(),
    route: {
      modes: this.model.modes(),
      summary: this.model.summary()
    }
  });

  var scrollable = document.querySelector('.scrollable');
  scrollable.scrollTop = el.offsetTop - 52;
};

View.prototype.hideDetails = function(e) {
  e.preventDefault();
  var list = this.el.classList;
  if (list.contains('expanded')) {
    list.remove('expanded');
  }
};

/**
 * Get the option number for display purposes (1-based)
 */

View.prototype.optionNumber = function() {
  return this.model.index + 1;
};

/**
 * View
 */

View.prototype.feedback = function(e) {
  e.preventDefault();
  Feedback(this.model).show();
};

/**
 * Select this option
 */

View.prototype.selectOption = function() {
  var route = this.model;
  var plan = session.plan();
  var tags = route.tags(plan);

  analytics.send_ga({
    category: 'route-card',
    action: 'select route',
    label: JSON.stringify(tags),
    value: 1
  });
  routeResource.findByTags(tags, function(err, resources) {
    var routeModal = new RouteModal(route, null, {
      context: 'route-card',
      resources: resources
    });
    routeModal.show();
    routeModal.on('next', function() {
      routeModal.hide();
    });
  });
};
<|endoftext|>


<commit_before>/* global describe, it, expect */

var Strategy = require('../lib/strategy');

describe('Strategy', function() {

  var strategy = new Strategy();

  it('authenticate should throw error', function() {
    expect(function() {
      strategy.authenticate();
    }).to.throw(Error, 'Strategy#authenticate must be overridden by subclass');
  });

});
<commit_msg>remove useless test<commit_after><|endoftext|>


<commit_before>/**
 * This file is part of agora-gui-elections.
 * Copyright (C) 2015-2016  Agora Voting SL <agora@agoravoting.com>

 * agora-gui-elections is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.

 * agora-gui-elections  is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.

 * You should have received a copy of the GNU Affero General Public License
 * along with agora-gui-elections.  If not, see <http://www.gnu.org/licenses/>.
**/

/*
 * Shows the public view of an election. Controls mainly the changing inner states
 * loading config, showing results, showing error if needed.
 */
angular.module('avElection').controller('PublicController',
  function($state, $stateParams, $http, $scope, $i18next, ConfigService, InsideIframeService, Authmethod) {
//     $state.go('election.public.loading');

    var mapLayouts = {
      "": "default",
      "simple": "default",
      "pcandidates-election": "default",
      "2questions-conditional": "default",
      "conditional-accordion": "default",
      "ahoram-primaries": "default"
    };
    $("#theme").attr("href", "election/themes/" + ConfigService.theme + "/app.min.css");
    //window.avThemes.change(ConfigService.theme);
    $scope.layout = mapLayouts["simple"];
    $scope.statePrefix = "election.public.show.home";
    $scope.inside_iframe = InsideIframeService();
    $scope.legal_html_include = ConfigService.legal_html_include;

    // get election config
    var extra_data  = {};
    $http.get(ConfigService.authAPI + "legal/" + $stateParams.id + "/")
      .then(function(value) {
        if(value.data) {
          extra_data = value.data;
        }
        return $http.get(ConfigService.baseUrl + "election/" + $stateParams.id + "/");
      })
      .then(function(value) {
        $scope.election = value.data.payload.configuration;
        $scope.election.extra_data = extra_data;
        $scope.layout = mapLayouts[$scope.election.layout];
        $scope.electionState = value.data.payload.state;
        $scope.results = angular.fromJson(value.data.payload.results);
      })
      // on error, like parse error or 404
      .catch(function (error) {
        $state.go("election.public.error");
      });

    Authmethod.viewEvent($stateParams.id)
      .success(function(data) {
        if (data.status === "ok") {
          $scope.authEvent = data.events;
        }
      });
  }
);
<commit_msg>test fix<commit_after>/**
 * This file is part of agora-gui-elections.
 * Copyright (C) 2015-2016  Agora Voting SL <agora@agoravoting.com>

 * agora-gui-elections is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.

 * agora-gui-elections  is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.

 * You should have received a copy of the GNU Affero General Public License
 * along with agora-gui-elections.  If not, see <http://www.gnu.org/licenses/>.
**/

/*
 * Shows the public view of an election. Controls mainly the changing inner states
 * loading config, showing results, showing error if needed.
 */
angular.module('avElection').controller('PublicController',
  function($state, $stateParams, $http, $scope, $i18next, ConfigService, InsideIframeService, Authmethod) {
//     $state.go('election.public.loading');

    var mapLayouts = {
      "": "default",
      "simple": "default",
      "pcandidates-election": "default",
      "2questions-conditional": "default",
      "conditional-accordion": "default",
      "ahoram-primaries": "default"
    };
    $("#theme").attr("href", "election/themes/" + ConfigService.theme + "/app.min.css");
    //window.avThemes.change(ConfigService.theme);
    $scope.layout = mapLayouts["simple"];
    $scope.statePrefix = "election.public.show.home";
    $scope.inside_iframe = InsideIframeService();
    $scope.legal_html_include = ConfigService.legal_html_include;

    // get election config
    var extra_data  = {};
    $http.get(ConfigService.authAPI + "legal/" + $stateParams.id + "/")
      .then(function(value) {
        if(value.data) {
          extra_data = value.data;
        }
        return $http.get(ConfigService.baseUrl + "election/" + $stateParams.id);
      })
      .then(function(value) {
        $scope.election = value.data.payload.configuration;
        $scope.election.extra_data = extra_data;
        $scope.layout = mapLayouts[$scope.election.layout];
        $scope.electionState = value.data.payload.state;
        $scope.results = angular.fromJson(value.data.payload.results);
      })
      // on error, like parse error or 404
      .catch(function (error) {
        $state.go("election.public.error");
      });

    Authmethod.viewEvent($stateParams.id)
      .success(function(data) {
        if (data.status === "ok") {
          $scope.authEvent = data.events;
        }
      });
  }
);
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var request = require('request');
var parseString = require('xml2js').parseString;

var isOnTravis = process.env.CIRCLECI === 'true';
var isOnTravisAndMaster = isOnTravis && process.env.CI_PULL_REQUEST === '' && process.env.CIRCLE_BRANCH === 'master';
var version;

parseString(fs.readFileSync('CellStore.dll.nuspec', 'utf-8'), { async: false }, function (err, result) {
    version = result.package.metadata[0].version[0];
});

gulp.task('swagger:clean', $.shell.task([
   'rm -rf build',
   'mkdir build'
]));

gulp.task('swagger:resolve', ['swagger:clean'], function(done){
    request({ url: 'http://28msec.github.io/cellstore-pro/swagger-aggregated.json' }, function(err, resp){
        fs.writeFileSync('build/swagger-aggregated.json', resp.body);
        done();
    });
});

gulp.task('swagger:install-codegen', ['swagger:resolve'], $.shell.task('cd build && curl -L -o swagger-codegen.zip https://github.com/28msec/swagger-codegen/archive/2149dc04d52811cbf89ac72ab17a57be6a6150ac.zip && unzip -q swagger-codegen.zip && cd swagger-codegen-2149dc04d52811cbf89ac72ab17a57be6a6150ac && mvn package && cp modules/swagger-codegen-cli/target/swagger-codegen-cli.jar ..'));

gulp.task('swagger:generate-csharp', ['swagger:install-codegen'], $.shell.task([
    'cd build && java -jar swagger-codegen-cli.jar generate -i swagger-aggregated.json -l csharp -c codegen-options  -o .'
]));

gulp.task('swagger:csharp', ['swagger:generate-csharp'], $.shell.task([
    'cd build && mcs -sdk:4.5 -r:bin/Newtonsoft.Json.dll,bin/RestSharp.dll,System.Runtime.Serialization.dll -target:library -out:bin/CellStore.dll -recurse:src/*.cs -doc:bin/CellStore.xml -platform:anycpu'
]));

gulp.task('swagger:pack', $.shell.task([
    'cp CellStore.dll.nuspec build',
    'cd build && wget https://nuget.org/nuget.exe',
    'cd build && mono nuget.exe pack CellStore.dll.nuspec'
]));

gulp.task('swagger:push', $.shell.task([
    'cd build && mono nuget.exe setApiKey ' + process.env.NUGET_API_KEY + ' | cat &> /dev/null',
    'cd build && mono nuget.exe push CellStore.NET.' + version + '.nupkg'
]));

gulp.task('swagger', function(done){
    if(isOnTravisAndMaster) {
        $.runSequence('swagger:csharp', 'swagger:pack', 'swagger:push', done);
    } else {
        $.runSequence('swagger:csharp', done);
    }
});

gulp.task('default', ['swagger']);
<commit_msg>:green_heart:<commit_after>'use strict';

var fs = require('fs');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var request = require('request');
var parseString = require('xml2js').parseString;

var isOnTravis = process.env.CIRCLECI === 'true';
var isOnTravisAndMaster = isOnTravis && process.env.CI_PULL_REQUEST === '' && process.env.CIRCLE_BRANCH === 'master';
var version;

parseString(fs.readFileSync('CellStore.dll.nuspec', 'utf-8'), { async: false }, function (err, result) {
    version = result.package.metadata[0].version[0];
});

gulp.task('swagger:clean', $.shell.task([
   'rm -rf build',
   'mkdir build'
]));

gulp.task('swagger:resolve', ['swagger:clean'], function(done){
    request({ url: 'http://28msec.github.io/cellstore-pro/swagger-aggregated.json' }, function(err, resp){
        fs.writeFileSync('build/swagger-aggregated.json', resp.body);
        done();
    });
});

gulp.task('swagger:install-codegen', ['swagger:resolve'], $.shell.task('cd build && curl -L -o swagger-codegen.zip https://github.com/28msec/swagger-codegen/archive/2149dc04d52811cbf89ac72ab17a57be6a6150ac.zip && unzip -q swagger-codegen.zip && cd swagger-codegen-2149dc04d52811cbf89ac72ab17a57be6a6150ac && mvn package && cp modules/swagger-codegen-cli/target/swagger-codegen-cli.jar ..'));

gulp.task('swagger:generate-csharp', ['swagger:install-codegen'], $.shell.task([
    'cd build && java -jar swagger-codegen-cli.jar generate -i swagger-aggregated.json -l csharp -c codegen-options.json  -o .'
]));

gulp.task('swagger:csharp', ['swagger:generate-csharp'], $.shell.task([
    'cd build && mcs -sdk:4.5 -r:bin/Newtonsoft.Json.dll,bin/RestSharp.dll,System.Runtime.Serialization.dll -target:library -out:bin/CellStore.dll -recurse:src/*.cs -doc:bin/CellStore.xml -platform:anycpu'
]));

gulp.task('swagger:pack', $.shell.task([
    'cp CellStore.dll.nuspec build',
    'cd build && wget https://nuget.org/nuget.exe',
    'cd build && mono nuget.exe pack CellStore.dll.nuspec'
]));

gulp.task('swagger:push', $.shell.task([
    'cd build && mono nuget.exe setApiKey ' + process.env.NUGET_API_KEY + ' | cat &> /dev/null',
    'cd build && mono nuget.exe push CellStore.NET.' + version + '.nupkg'
]));

gulp.task('swagger', function(done){
    if(isOnTravisAndMaster) {
        $.runSequence('swagger:csharp', 'swagger:pack', 'swagger:push', done);
    } else {
        $.runSequence('swagger:csharp', done);
    }
});

gulp.task('default', ['swagger']);
<|endoftext|>


<commit_before>var fs  = require("fs"),
    path = require("path"),
    _ = require("underscore")._,
    inherits = require("inherits"),
    FSM = require("./fsm"),
    fileWatcher = require("./filewatcher"),
    Registry = require("./registry");

/**
 * @class This class represents a resource publisher / cache.  It allows multiple components to be aggregated together into one cache, and published on demand.
 * @param {Object} options
 * @extends EventPublisher
 */
function ResourcePublisher(options) {
  ResourcePublisher.super.apply(this, arguments);
  this.id = options.cacheName;
  this.contentType = options.contentType;
  this.publisherOptions = options.publisherOptions;
  this.content = "";
  this.components = {};
  this.componentOrder = [];
  this.valid = false;
  this.cachePathValid = false;
  this.publishers = new Registry();
};

ResourcePublisher.prototype = {
  /**
   * Invalidates this publisher's cache and fires an invalidated event.
   */
  states: {
    initial: {
      publish: function(options, callback) {
        return this.states.publishing;
      }
    },
    publishing: {
      stateStartup: function(options, callback) {
        var me = this;
        var publisher = null;
        debugger;
        if (options.publisherId || options.id) {
          var id = options.publisherId || options.id;
          publisher = this.publishers.findById(id);
        } else if (options.publisher) {
          publisher = options.publisher;
        } else {
          // go boom.
        }
        if (publisher) {
          publisher.publish(options, this, function(err, publishResult) {
            if (err) (callback && callback(err)); else {
              me.fire("published", publishResult, callback);
            }
          });
        } else {
           // No publisher specified. Error condition.
          callback && callback("No underlying publisher was specified. Cannot publish.");

          //go back to previous state in case calling code wants to try to resolve the situation and try again
          return this.previousState;
        }
      },
      //allows additional pseudo-requests to queue up
      publish: function(options, callback) {
        var me = this;
        this.onceState("published", function(publishResult, callback) {
          callback && callback(null, publishResult);
        });
      },
      published: function(publishResult, callback) {
        return this.states.published;
      }
    },
    published: {
      stateStartup: function(publishResult, callback) {
        this.publishResult = publishResult;
        callback && callback(null, publishResult);
      },
      publish: function(options, callback) {
        callback && callback(null, this.publishResult);
      }
    }
  },
  invalidate: function() {
    this.valid = false;
    this.fire('invalidated');
  },

  makeReady: function() {
    //let the FSM handle things...
    this.fire("ready");
  },
  addComponent: function(options, callback) {
    var me = this,
      name = options.name,
      content = options.content,
      index = options.index,
      url = options.url;

    var component = {
      content: content,
      index: index,
      url: url,
      changeListener: function(args) {
        me.componentChanged(name);
      },
      watching: false
    };

    this.components[name] = component;
    this.componentOrder.push(name);
    this.componentOrder = _.sortBy(this.componentOrder, function(compName) {
      return me.components[compName].index;
    });
    // Only watch the name if the file exists and it's a file!
    path.exists(name, function(exists) {
      if (exists) {
        fs.stat(name, function(err, stats) {
          if (err) {
            this.removeComponent(name);
            callback && callback(err);
          } else if (stats.isFile()) {
            component.watching = true;
            fileWatcher.watchFileMtime(name, component.changeListener);
            callback && callback(null, component);
            me.fire('componentAdded', component);
          }
        });
      } else {
        callback && callback("path " + name + " does not exist.");
        this.fire('componentAdded', component);
      }
    });
  },

  /**
   * Removes the named component from this publisher.  Fires "componentRemoved" event on completion.
   * @param {String} name the component to remove.
   */
  removeComponent: function(name) {
    if (this.components[name]) {
      var component = this.components[name];
      this.components[name] = null;
      this.componentOrder = _.reject(this.componentOrder, function(it) { return it === name; });
      if (component.watching) {
        fileWatcher.unwatchFile(name, component.changeListener);
      }
      this.fire('componentRemoved', name);
    }
  },
  concat: function() {
    var content = "";
    for (var i = 0; i < this.componentOrder.length; i++) {
      var name = this.componentOrder[i];
      content += "\n\n/* ========== " + path.basename(name) + " ========== */\n\n" + this.components[name].content;
    }
    return content;
  },
  publish: function(options, callback) {
    this.fire("publish", options, callback); //let the fsm control the rest
  },
  componentChanged: function(name) {
    var me = this;
    var oldContent = this.components[name];
    fs.readFile(name, "utf8", function(err, data) {
      if (err) {
      } else {
        me.components[name].content = data;
        me.fire('componentChanged', name);
      }
    });
  },
  /**
   * Diposes of this publisher.  All components are disposed of and any watched files are cleaned up before disposing.
   */
  dispose: function() {
    // Dispose of all of the components.
    for (var i = 0; i < this.componentOrder.length; i++) {
      var name = this.componentOrder[i];
      if (this.components[name].watching) {
        fileWatcher.unwatchFile(name, this.components[name].changeListener);
      }
      this.components[name] = null;
    }
    ResourcePublisher.super.prototype.dispose.apply(this, arguments);
  }
};
inherits(ResourcePublisher, FSM);
module.exports = ResourcePublisher;<commit_msg>Removed de bugger.<commit_after>var fs  = require("fs"),
    path = require("path"),
    _ = require("underscore")._,
    inherits = require("inherits"),
    FSM = require("./fsm"),
    fileWatcher = require("./filewatcher"),
    Registry = require("./registry");

/**
 * @class This class represents a resource publisher / cache.  It allows multiple components to be aggregated together into one cache, and published on demand.
 * @param {Object} options
 * @extends EventPublisher
 */
function ResourcePublisher(options) {
  ResourcePublisher.super.apply(this, arguments);
  this.id = options.cacheName;
  this.contentType = options.contentType;
  this.publisherOptions = options.publisherOptions;
  this.content = "";
  this.components = {};
  this.componentOrder = [];
  this.valid = false;
  this.cachePathValid = false;
  this.publishers = new Registry();
};

ResourcePublisher.prototype = {
  /**
   * Invalidates this publisher's cache and fires an invalidated event.
   */
  states: {
    initial: {
      publish: function(options, callback) {
        return this.states.publishing;
      }
    },
    publishing: {
      stateStartup: function(options, callback) {
        var me = this;
        var publisher = null;
        if (options.publisherId || options.id) {
          var id = options.publisherId || options.id;
          publisher = this.publishers.findById(id);
        } else if (options.publisher) {
          publisher = options.publisher;
        } else {
          // go boom.
        }
        if (publisher) {
          publisher.publish(options, this, function(err, publishResult) {
            if (err) (callback && callback(err)); else {
              me.fire("published", publishResult, callback);
            }
          });
        } else {
           // No publisher specified. Error condition.
          callback && callback("No underlying publisher was specified. Cannot publish.");

          //go back to previous state in case calling code wants to try to resolve the situation and try again
          return this.previousState;
        }
      },
      //allows additional pseudo-requests to queue up
      publish: function(options, callback) {
        var me = this;
        this.onceState("published", function(publishResult, callback) {
          callback && callback(null, publishResult);
        });
      },
      published: function(publishResult, callback) {
        return this.states.published;
      }
    },
    published: {
      stateStartup: function(publishResult, callback) {
        this.publishResult = publishResult;
        callback && callback(null, publishResult);
      },
      publish: function(options, callback) {
        callback && callback(null, this.publishResult);
      }
    }
  },
  invalidate: function() {
    this.valid = false;
    this.fire('invalidated');
  },

  makeReady: function() {
    //let the FSM handle things...
    this.fire("ready");
  },
  addComponent: function(options, callback) {
    var me = this,
      name = options.name,
      content = options.content,
      index = options.index,
      url = options.url;

    var component = {
      content: content,
      index: index,
      url: url,
      changeListener: function(args) {
        me.componentChanged(name);
      },
      watching: false
    };

    this.components[name] = component;
    this.componentOrder.push(name);
    this.componentOrder = _.sortBy(this.componentOrder, function(compName) {
      return me.components[compName].index;
    });
    // Only watch the name if the file exists and it's a file!
    path.exists(name, function(exists) {
      if (exists) {
        fs.stat(name, function(err, stats) {
          if (err) {
            this.removeComponent(name);
            callback && callback(err);
          } else if (stats.isFile()) {
            component.watching = true;
            fileWatcher.watchFileMtime(name, component.changeListener);
            callback && callback(null, component);
            me.fire('componentAdded', component);
          }
        });
      } else {
        callback && callback("path " + name + " does not exist.");
        this.fire('componentAdded', component);
      }
    });
  },

  /**
   * Removes the named component from this publisher.  Fires "componentRemoved" event on completion.
   * @param {String} name the component to remove.
   */
  removeComponent: function(name) {
    if (this.components[name]) {
      var component = this.components[name];
      this.components[name] = null;
      this.componentOrder = _.reject(this.componentOrder, function(it) { return it === name; });
      if (component.watching) {
        fileWatcher.unwatchFile(name, component.changeListener);
      }
      this.fire('componentRemoved', name);
    }
  },
  concat: function() {
    var content = "";
    for (var i = 0; i < this.componentOrder.length; i++) {
      var name = this.componentOrder[i];
      content += "\n\n/* ========== " + path.basename(name) + " ========== */\n\n" + this.components[name].content;
    }
    return content;
  },
  publish: function(options, callback) {
    this.fire("publish", options, callback); //let the fsm control the rest
  },
  componentChanged: function(name) {
    var me = this;
    var oldContent = this.components[name];
    fs.readFile(name, "utf8", function(err, data) {
      if (err) {
      } else {
        me.components[name].content = data;
        me.fire('componentChanged', name);
      }
    });
  },
  /**
   * Diposes of this publisher.  All components are disposed of and any watched files are cleaned up before disposing.
   */
  dispose: function() {
    // Dispose of all of the components.
    for (var i = 0; i < this.componentOrder.length; i++) {
      var name = this.componentOrder[i];
      if (this.components[name].watching) {
        fileWatcher.unwatchFile(name, this.components[name].changeListener);
      }
      this.components[name] = null;
    }
    ResourcePublisher.super.prototype.dispose.apply(this, arguments);
  }
};
inherits(ResourcePublisher, FSM);
module.exports = ResourcePublisher;<|endoftext|>


<commit_before>Template.RDRWidget.helpers({
  services: function() {
    return RDRData.find({ category: this.category });
  },
  serviceSlug: function() {
    return s.slugify(this.service);
  },
  metrics: function() {
    return Settings.metrics;
  },
  isSorted: function() {
    return this.name === Template.parentData().sortMetric ? 'sorted' : 'not-sorted';
  },
  isTilted: function() {
    return this.tilted ? 'tilted' : '';
  }
});

Template.RDRWidget.onCreated(function() {
  var template = this;
  template.autorun(function() {
    template.subscribe('ranking_digital_rights', Template.currentData().category);
  });
});

Template.RDRWidget.onRendered(function() {
  var template = this;
  var pieColors = d3.scale.category10();
  var $serviceList = template.$('table tbody');
  template.autorun(function() {
    if (!template.subscriptionsReady()) { return; }

    var category = Template.currentData().category;
    var sort = Template.currentData().sortMetric;
    var $metrics, serviceSlug, data, selector, cell;

    $serviceList.empty();

    var records = RDRData.find({ category: category }).fetch();
    records = _.sortBy(records, function(record) {
      return _.findWhere(record.service_metrics, { name: sort }).rank;
    });
    records.forEach(function(record) {
      serviceSlug = s.slugify(record.service);
      $serviceList.append(
        '
' +
          '
' + record.service +  (_.contains(['Mobile','Fixed broadband'],record.category) ? ' (' + record.country +')' : '') + '

' + record.company + '
	' + '
');

      selector = '.service-' + serviceSlug;
      metricsNode = template.find(selector);

      Settings.metrics.forEach(function(metric) {
        var serviceMetricData = _.findWhere(record.service_metrics, { name: metric.name });
        var companyMetricData = _.findWhere(record.company_metrics, { name: metric.name });
        data = [serviceMetricData.value, 100.0 - serviceMetricData.value, companyMetricData.value];
        cell = $('').addClass('text-center').appendTo(metricsNode).get(0);
        radius = metric.name === Settings.totalMetric ?
          Settings.pie.totalRadius : Settings.pie.radius;
        drawGraph(cell, data, radius, pieColors(metric.name));
      });
    });
  });
});

function drawGraph(parent, data, radius, color) {
  var width     = radius,
      height    = radius +30;
  var pieRadius = radius / 2;

  var arc = d3.svg.arc()
    .outerRadius(pieRadius)
    .innerRadius(Settings.pie.innerRadius);

  var pie = d3.layout.pie().startAngle(Math.PI).endAngle(3 * Math.PI).sort(null);

  var svg = d3.select(parent).append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + radius / 2 + "," + radius / 2 + ")");

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

  g.append("path")
    .attr("d", arc)
    .style("fill", function(d, i) {
      return i === 0 ? color: Settings.pie.background;
    });

  svg.append('text')
    .attr('text-anchor', 'middle')
    .attr('y', 4)
    .text(Math.round(data[0]));

  svg.append('text')
    .attr('class','company-score')
    .attr('text-anchor', 'middle')
    .attr('alignment-baseline','hanging')
    .attr('y', radius/2+8)
    .text(Math.round(data[2]));

}
<commit_msg>Fix RDR pie charts percents off<commit_after>Template.RDRWidget.helpers({
  services: function() {
    return RDRData.find({ category: this.category });
  },
  serviceSlug: function() {
    return s.slugify(this.service);
  },
  metrics: function() {
    return Settings.metrics;
  },
  isSorted: function() {
    return this.name === Template.parentData().sortMetric ? 'sorted' : 'not-sorted';
  },
  isTilted: function() {
    return this.tilted ? 'tilted' : '';
  }
});

Template.RDRWidget.onCreated(function() {
  var template = this;
  template.autorun(function() {
    template.subscribe('ranking_digital_rights', Template.currentData().category);
  });
});

Template.RDRWidget.onRendered(function() {
  var template = this;
  var pieColors = d3.scale.category10();
  var $serviceList = template.$('table tbody');
  template.autorun(function() {
    if (!template.subscriptionsReady()) { return; }

    var category = Template.currentData().category;
    var sort = Template.currentData().sortMetric;
    var $metrics, serviceSlug, data, selector, cell;

    $serviceList.empty();

    var records = RDRData.find({ category: category }).fetch();
    records = _.sortBy(records, function(record) {
      return _.findWhere(record.service_metrics, { name: sort }).rank;
    });
    records.forEach(function(record) {
      serviceSlug = s.slugify(record.service);
      $serviceList.append(
        '
' +
          '
' + record.service +  (_.contains(['Mobile','Fixed broadband'],record.category) ? ' (' + record.country +')' : '') + '

' + record.company + '
	' + '
');

      selector = '.service-' + serviceSlug;
      metricsNode = template.find(selector);

      Settings.metrics.forEach(function(metric) {
        var serviceMetricData = _.findWhere(record.service_metrics, { name: metric.name });
        var companyMetricData = _.findWhere(record.company_metrics, { name: metric.name });
        data = [serviceMetricData.value, 100.0 - serviceMetricData.value, companyMetricData.value];
        cell = $('').addClass('text-center').appendTo(metricsNode).get(0);
        radius = metric.name === Settings.totalMetric ?
          Settings.pie.totalRadius : Settings.pie.radius;
        drawGraph(cell, data, radius, pieColors(metric.name));
      });
    });
  });
});

function drawGraph(parent, data, radius, color) {

  var width     = radius,
      height    = radius +30;
  var pieRadius = radius / 2;

  var arc = d3.svg.arc()
    .outerRadius(pieRadius)
    .innerRadius(Settings.pie.innerRadius);

  var pie = d3.layout.pie().startAngle(Math.PI).endAngle(3 * Math.PI).sort(null);

  var svg = d3.select(parent).append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + radius / 2 + "," + radius / 2 + ")");

  var g = svg.selectAll(".arc")
      .data(pie([data[0],data[1]]))
    .enter().append("g")
    .attr("class", "arc");

  g.append("path")
    .attr("d", arc)
    .style("fill", function(d, i) {
      return i === 0 ? color: Settings.pie.background;
    });

  svg.append('text')
    .attr('text-anchor', 'middle')
    .attr('y', 4)
    .text(Math.round(data[0]));

  svg.append('text')
    .attr('class','company-score')
    .attr('text-anchor', 'middle')
    .attr('alignment-baseline','hanging')
    .attr('y', radius/2+8)
    .text(Math.round(data[2]));

}
<|endoftext|>


<commit_before>import React from 'react';
import { browserHistory } from 'react-router';
import { connect } from 'react-redux';
import {
  Table,
  TableBody,
  TableHeader,
  TableHeaderColumn,
  TableRow,
  TableRowColumn
} from 'material-ui/Table';
import { Tabs, Tab } from 'material-ui/Tabs';
import FlatButton from 'material-ui/FlatButton';
import Navbar from './reusable/Navbar.component';
import Paginate from './reusable/Paginate.component';
import CustomDrawer from './CustomDrawer.component';
import DeleteDialog from './DeleteDialog.component';
import {
  getActiveUser,
  getAllUsers,
  updateUser,
  deleteUser,
  confirmDeleteUser,
  clearConfirmDeleteUser,
  confirmPromotion,
  clearConfirmPromotion
} from '../actions/users.action';
import { getAllDocs, deleteDoc, clearConfirmDeleteDoc, confirmDeleteDoc } from '../actions/document.action';
import getUserInfo from '../util/getUserInfo';
import paginate from '../util/paginate';

@connect(store => ({
  user: store.users,
  form: store.form,
  error: store.error.error,
  auth: store.auth,
  docs: store.documents,
  folder: store.folder,
  views: store.views
}))
/**
*
* Compoent to diplay and manage users
* @class ManageUser
*/
class ManageUser extends React.Component {

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleUserPageChange = this.handleUserPageChange.bind(this);
    this.handleConfirmDeleteDoc = this.handleConfirmDeleteDoc.bind(this);
    this.clearDeleteConfirmation = this.clearDeleteConfirmation.bind(this);
    this.handleDeleteDoc = this.handleDeleteDoc.bind(this);
    this.clearDeleteUserConfirmation = this.clearDeleteUserConfirmation.bind(this);
    this.handleDeleteUser = this.handleDeleteUser.bind(this);
    this.handleConfirmDeleteUser = this.handleConfirmDeleteUser.bind(this);
    this.handleDocPageChange= this.handleDocPageChange.bind(this);
    this.confirmPromotion = this.confirmPromotion.bind(this);
    this.clearConfirmPromotion = this.clearConfirmPromotion.bind(this);
    this.handlePromoteUser = this.handlePromoteUser.bind(this);
    this.state = { value: 'users', user_page: 1, doc_page: 1 };
  }

  /**
   * componentDidMount
   * @return {void}
   */
  componentDidMount() {
    if (!window.localStorage.getItem('token')) {
      browserHistory.push('/app/login');
    } else {
      this.props.dispatch(getActiveUser());
      this.props.dispatch(getAllUsers(7, 0));
      this.props.dispatch(getAllDocs(7, 0));
    }
  }

  /**
   * componentWillReceiveProps
   * @param {object} nextProps - next properties the component will recieve
   * before render
   * @return {void}
   */
  componentWillReceiveProps(nextProps) {
    if (nextProps.user.details) {
      if (nextProps.user.details.roleId
        && nextProps.user.details.roleId !== 1) {
        browserHistory.push('/app/dashboard');
      }
    }
  }

  handlePromoteUser(id) {
    this.props.dispatch(updateUser(id, { roleId: 1 }));
  }

  handleDeleteUser(id) {
    this.props.dispatch(deleteUser(id));
  }

  handleChange(value) {
    this.setState({ value });
  }

   /**
    * handleConfirmDeleteUser - send an action to confirm user delete
    * @param {Object} values - information to pass to the delete dialog
    */
   handleConfirmDeleteUser(values) {
     this.props.dispatch(confirmDeleteUser(values));
   }

   /**
    * clearDeleteUserConfirmation
    * @return {void}
    */
   clearDeleteUserConfirmation() {
     this.props.dispatch(clearConfirmDeleteUser());
   }

  /**
   * handleConfirmDeleteDoc
   * @param {object} values - object to render confirmation dialog with
   * @return {void}
   */
  handleConfirmDeleteDoc(values) {
    this.props.dispatch(confirmDeleteDoc({
      id: values.id,
      title: values.title,
      type: 'document'
    }));
  }

  /**
   * clearDeleteConfirmation
   * @return {void}
   */
  clearDeleteConfirmation() {
    this.props.dispatch(clearConfirmDeleteDoc());
  }

  /**
   * handleDeleteDoc
   * @param {object} id - document id to delete
   * @return {void}
   */
  handleDeleteDoc(id) {
    this.props.dispatch(deleteDoc(id));
  }

  /**
   * handlePageChange - set the state of the component to the
   * current value of the selected option and dispatch a page change
   * action
   * @param {object} event - properties of the select fields
   * @param {number} index - index number of selected option
   * @param {string} value - value of the selected option
   * @return {void}
   */
  handleUserPageChange(event, index, value) {
    this.setState({ user_page: value });
    const offset = 7 * (value - 1);
    this.props.dispatch(getAllUsers(7, offset));
  }

  /**
   * handleDocPageChange - set the state of the component to the
   * current value of the selected option and dispatch a page change
   * action
   * @param {object} event - properties of the select fields
   * @param {number} index - index number of selected option
   * @param {string} value - value of the selected option
   * @return {void}
   */
  handleDocPageChange(event, index, value) {
    this.setState({ doc_page: value });
    const offset = 7 * (value - 1);
    this.props.dispatch(getAllDocs(7, offset));
  }

  /**
   * confirmPromotion
   * @param {Object} values - information to render promotion
   * dialog with
   * @return {void}
   */
  confirmPromotion(values) {
    this.props.dispatch(confirmPromotion(values));
  }

  /**
   * clearConfirmPromotion
   * @return {void}
   */
  clearConfirmPromotion() {
    this.props.dispatch(clearConfirmPromotion());
  }

  renderTable(users) {
    const self = this;
    return users.users.results.map((user, index) => (
      <TableRow key={`${index}tablerow-user`}>
        <TableRowColumn>
          {user.id}
        </TableRowColumn>
        <TableRowColumn>
          {user.firstname}
        </TableRowColumn>
        <TableRowColumn>
          {user.lastname}
        </TableRowColumn>
        <TableRowColumn>
          {user.username}
        </TableRowColumn>
        <TableRowColumn>{
          (user.roleId === 1) ?
            'Admin' :
            <FlatButton
              label="Promote"
              primary
              onTouchTap={() => self.confirmPromotion({
                id:user.id,
                title: user.username,
                type: 'admin'
              })}
            />
          }
        </TableRowColumn>
        <TableRowColumn key={index + user.id + user.firstname}>
          {user.email}</TableRowColumn>
        <TableRowColumn key={index + user.id + user.firstname}>{
          (user.roleId === 1) ?
            '' :
            <FlatButton
              key={`${index}flat${user.id}`}
              label="Delete"
              secondary
              onTouchTap={() => self.handleConfirmDeleteUser({
                id: user.id,
                title: user.username,
                type: 'user'
              })}
            />
          }
        </TableRowColumn>
      </TableRow>
    ));
  }

  renderDocuments(docs) {
    const self = this;
    const accessLevels = {
      1: 'Public',
      2: 'Private',
      3: 'Role'
    };
    return docs.results.map((doc, index) => (
      <TableRow key={`${doc.id}${doc.title}`}>
        <TableRowColumn>
          {doc.id}
        </TableRowColumn>
        <TableRowColumn>
          {doc.title}
        </TableRowColumn>
        <TableRowColumn>
          <FlatButton
            key={`${index}flat-view${doc.id}`}
            primary
            onTouchTap={() => browserHistory.push(`/app/document/${doc.id}`)}
            label="View"
          />
        </TableRowColumn>
        <TableRowColumn>
          {accessLevels[doc.accessId]}
        </TableRowColumn>
        <TableRowColumn>
          {doc.User.username}
        </TableRowColumn>
        <TableRowColumn>
          {(doc.User.roleId === 1
              && doc.ownerId !== doc.User.id) ?
            ''
            :
            <FlatButton
              key={`${index}flat${doc.id}`}
              label="Delete"
              secondary
              onTouchTap={() => self.handleConfirmDeleteDoc({
                id: doc.id,
                title: doc.title
              })}
            />
          }
        </TableRowColumn>
      </TableRow>
    ));
  }

  /**
   * render
   * @return {object} react elements to render
   */
  render() {
    const users = this.props.user.users;
    const allDocuments = this.props.docs.allDocuments;
    return (

        <DeleteDialog
          onDelete={this.handleDeleteUser}
          openDialog={this.handleConfirmDeleteUser}
          onDeleteConfirmation={this.props.user.confirmDelete}
          clearDeleteConfirmation={this.clearDeleteUserConfirmation}
        />
        <DeleteDialog
          onDelete={this.handleDeleteDoc}
          openDialog={this.handleConfirmDeleteDoc}
          onDeleteConfirmation={this.props.docs.confirmDelete}
          clearDeleteConfirmation={this.clearDeleteConfirmation}
        />
        <DeleteDialog
          title="Promote User"
          onDelete={this.handlePromoteUser}
          openDialog={this.confirmPromotion}
          onDeleteConfirmation={this.props.user.promotion}
          clearDeleteConfirmation={this.clearConfirmPromotion}
          message="Are you sure you want to promote this user?"
        />
        {(this.props.user.users && this.props.docs.allDocuments) ?

              <Tabs value={this.state.value} onChange={this.handleChange}>
                <Tab label="Manage Users" value="users">

                      <TableHeader displayRowCheckbox={false}>
                        <TableRow>
                          <TableHeaderColumn>ID</TableHeaderColumn>
                          <TableHeaderColumn>First Name</TableHeaderColumn>
                          <TableHeaderColumn>Last Name</TableHeaderColumn>
                          <TableHeaderColumn>Username</TableHeaderColumn>
                          <TableHeaderColumn>Role</TableHeaderColumn>
                          <TableHeaderColumn>Email</TableHeaderColumn>
                          <TableHeaderColumn>Delete</TableHeaderColumn>
                        </TableRow>
                      </TableHeader>
                      <TableBody displayRowCheckbox={false}>
                        {this.renderTable(users)}
                      </TableBody>

                      <Paginate
                        pageCount={users.users.paginationMeta.page_count}
                        page={this.state.user_page}
                        handlePageChange={this.handleUserPageChange}
                      />

                </Tab>
                <Tab label="Manage Documents" value="docs">

                    <TableHeader displayRowCheckbox={false}>
                      <TableRow>
                        <TableHeaderColumn>ID</TableHeaderColumn>
                        <TableHeaderColumn>Title</TableHeaderColumn>
                        <TableHeaderColumn>Content</TableHeaderColumn>
                        <TableHeaderColumn>Access Level</TableHeaderColumn>
                        <TableHeaderColumn>Author</TableHeaderColumn>
                        <TableHeaderColumn>Delete</TableHeaderColumn>
                      </TableRow>
                    </TableHeader>
                    <TableBody displayRowCheckbox={false}>
                      {this.renderDocuments(this.props.docs.allDocuments)}
                    </TableBody>

                    <Paginate
                      pageCount={allDocuments.paginationMeta.page_count}
                      page={this.state.doc_page}
                      handlePageChange={this.handleDocPageChange}
                    />

                </Tab>
              </Tabs>

          :
          ''
        }

    );
  }
}

export default ManageUser;
<commit_msg>feature(paginate-table): fix redirect issuses on manage page[144919429]<commit_after>import React from 'react';
import { browserHistory } from 'react-router';
import { connect } from 'react-redux';
import {
  Table,
  TableBody,
  TableHeader,
  TableHeaderColumn,
  TableRow,
  TableRowColumn
} from 'material-ui/Table';
import { Tabs, Tab } from 'material-ui/Tabs';
import FlatButton from 'material-ui/FlatButton';
import Navbar from './reusable/Navbar.component';
import Paginate from './reusable/Paginate.component';
import CustomDrawer from './CustomDrawer.component';
import DeleteDialog from './DeleteDialog.component';
import {
  getActiveUser,
  getAllUsers,
  updateUser,
  deleteUser,
  confirmDeleteUser,
  clearConfirmDeleteUser,
  confirmPromotion,
  clearConfirmPromotion
} from '../actions/users.action';
import { getAllDocs, deleteDoc, clearConfirmDeleteDoc, confirmDeleteDoc } from '../actions/document.action';
import getUserInfo from '../util/getUserInfo';
import paginate from '../util/paginate';

@connect(store => ({
  user: store.users,
  form: store.form,
  error: store.error.error,
  auth: store.auth,
  docs: store.documents,
  folder: store.folder,
  views: store.views
}))
/**
*
* Compoent to diplay and manage users
* @class ManageUser
*/
class ManageUser extends React.Component {

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleUserPageChange = this.handleUserPageChange.bind(this);
    this.handleConfirmDeleteDoc = this.handleConfirmDeleteDoc.bind(this);
    this.clearDeleteConfirmation = this.clearDeleteConfirmation.bind(this);
    this.handleDeleteDoc = this.handleDeleteDoc.bind(this);
    this.clearDeleteUserConfirmation = this.clearDeleteUserConfirmation.bind(this);
    this.handleDeleteUser = this.handleDeleteUser.bind(this);
    this.handleConfirmDeleteUser = this.handleConfirmDeleteUser.bind(this);
    this.handleDocPageChange= this.handleDocPageChange.bind(this);
    this.confirmPromotion = this.confirmPromotion.bind(this);
    this.clearConfirmPromotion = this.clearConfirmPromotion.bind(this);
    this.handlePromoteUser = this.handlePromoteUser.bind(this);
    this.state = { value: 'users', user_page: 1, doc_page: 1 };
  }

  /**
   * componentDidMount
   * @return {void}
   */
  componentDidMount() {
    if (!window.localStorage.getItem('token')) {
      browserHistory.push('/app/login');
    } else {
      this.props.dispatch(getActiveUser());
      this.props.dispatch(getAllUsers(7, 0));
      this.props.dispatch(getAllDocs(7, 0));
    }
  }

  /**
   * componentWillReceiveProps
   * @param {object} nextProps - next properties the component will recieve
   * before render
   * @return {void}
   */
  componentWillReceiveProps(nextProps) {
    if (nextProps.user.details) {
      if (nextProps.user.details.roleId
        && nextProps.user.details['Role.title'] !== 'admin') {
        browserHistory.push('/app/dashboard');
      }
    }
  }

  handlePromoteUser(id) {
    this.props.dispatch(updateUser(id, { roleId: 1 }));
  }

  handleDeleteUser(id) {
    this.props.dispatch(deleteUser(id));
  }

  handleChange(value) {
    this.setState({ value });
  }

   /**
    * handleConfirmDeleteUser - send an action to confirm user delete
    * @param {Object} values - information to pass to the delete dialog
    */
   handleConfirmDeleteUser(values) {
     this.props.dispatch(confirmDeleteUser(values));
   }

   /**
    * clearDeleteUserConfirmation
    * @return {void}
    */
   clearDeleteUserConfirmation() {
     this.props.dispatch(clearConfirmDeleteUser());
   }

  /**
   * handleConfirmDeleteDoc
   * @param {object} values - object to render confirmation dialog with
   * @return {void}
   */
  handleConfirmDeleteDoc(values) {
    this.props.dispatch(confirmDeleteDoc({
      id: values.id,
      title: values.title,
      type: 'document'
    }));
  }

  /**
   * clearDeleteConfirmation
   * @return {void}
   */
  clearDeleteConfirmation() {
    this.props.dispatch(clearConfirmDeleteDoc());
  }

  /**
   * handleDeleteDoc
   * @param {object} id - document id to delete
   * @return {void}
   */
  handleDeleteDoc(id) {
    this.props.dispatch(deleteDoc(id));
  }

  /**
   * handlePageChange - set the state of the component to the
   * current value of the selected option and dispatch a page change
   * action
   * @param {object} event - properties of the select fields
   * @param {number} index - index number of selected option
   * @param {string} value - value of the selected option
   * @return {void}
   */
  handleUserPageChange(event, index, value) {
    this.setState({ user_page: value });
    const offset = 7 * (value - 1);
    this.props.dispatch(getAllUsers(7, offset));
  }

  /**
   * handleDocPageChange - set the state of the component to the
   * current value of the selected option and dispatch a page change
   * action
   * @param {object} event - properties of the select fields
   * @param {number} index - index number of selected option
   * @param {string} value - value of the selected option
   * @return {void}
   */
  handleDocPageChange(event, index, value) {
    this.setState({ doc_page: value });
    const offset = 7 * (value - 1);
    this.props.dispatch(getAllDocs(7, offset));
  }

  /**
   * confirmPromotion
   * @param {Object} values - information to render promotion
   * dialog with
   * @return {void}
   */
  confirmPromotion(values) {
    this.props.dispatch(confirmPromotion(values));
  }

  /**
   * clearConfirmPromotion
   * @return {void}
   */
  clearConfirmPromotion() {
    this.props.dispatch(clearConfirmPromotion());
  }

  renderTable(users) {
    const self = this;
    return users.users.results.map((user, index) => (
      <TableRow key={`${index}tablerow-user`}>
        <TableRowColumn>
          {user.id}
        </TableRowColumn>
        <TableRowColumn>
          {user.firstname}
        </TableRowColumn>
        <TableRowColumn>
          {user.lastname}
        </TableRowColumn>
        <TableRowColumn>
          {user.username}
        </TableRowColumn>
        <TableRowColumn>{
          (user.roleId === 1) ?
            'Admin' :
            <FlatButton
              label="Promote"
              primary
              onTouchTap={() => self.confirmPromotion({
                id:user.id,
                title: user.username,
                type: 'admin'
              })}
            />
          }
        </TableRowColumn>
        <TableRowColumn key={index + user.id + user.firstname}>
          {user.email}</TableRowColumn>
        <TableRowColumn key={index + user.id + user.firstname}>{
          (user.roleId === 1) ?
            '' :
            <FlatButton
              key={`${index}flat${user.id}`}
              label="Delete"
              secondary
              onTouchTap={() => self.handleConfirmDeleteUser({
                id: user.id,
                title: user.username,
                type: 'user'
              })}
            />
          }
        </TableRowColumn>
      </TableRow>
    ));
  }

  renderDocuments(docs) {
    const self = this;
    const accessLevels = {
      1: 'Public',
      2: 'Private',
      3: 'Role'
    };
    return docs.results.map((doc, index) => (
      <TableRow key={`${doc.id}${doc.title}`}>
        <TableRowColumn>
          {doc.id}
        </TableRowColumn>
        <TableRowColumn>
          {doc.title}
        </TableRowColumn>
        <TableRowColumn>
          <FlatButton
            key={`${index}flat-view${doc.id}`}
            primary
            onTouchTap={() => browserHistory.push(`/app/document/${doc.id}`)}
            label="View"
          />
        </TableRowColumn>
        <TableRowColumn>
          {accessLevels[doc.accessId]}
        </TableRowColumn>
        <TableRowColumn>
          {doc.User.username}
        </TableRowColumn>
        <TableRowColumn>
          {(doc.User.roleId === 1
              && doc.ownerId !== doc.User.id) ?
            ''
            :
            <FlatButton
              key={`${index}flat${doc.id}`}
              label="Delete"
              secondary
              onTouchTap={() => self.handleConfirmDeleteDoc({
                id: doc.id,
                title: doc.title
              })}
            />
          }
        </TableRowColumn>
      </TableRow>
    ));
  }

  /**
   * render
   * @return {object} react elements to render
   */
  render() {
    const users = this.props.user.users;
    const allDocuments = this.props.docs.allDocuments;
    return (

        <DeleteDialog
          onDelete={this.handleDeleteUser}
          openDialog={this.handleConfirmDeleteUser}
          onDeleteConfirmation={this.props.user.confirmDelete}
          clearDeleteConfirmation={this.clearDeleteUserConfirmation}
        />
        <DeleteDialog
          onDelete={this.handleDeleteDoc}
          openDialog={this.handleConfirmDeleteDoc}
          onDeleteConfirmation={this.props.docs.confirmDelete}
          clearDeleteConfirmation={this.clearDeleteConfirmation}
        />
        <DeleteDialog
          title="Promote User"
          onDelete={this.handlePromoteUser}
          openDialog={this.confirmPromotion}
          onDeleteConfirmation={this.props.user.promotion}
          clearDeleteConfirmation={this.clearConfirmPromotion}
          message="Are you sure you want to promote this user?"
        />
        {(this.props.user.users && this.props.docs.allDocuments) ?

              <Tabs value={this.state.value} onChange={this.handleChange}>
                <Tab label="Manage Users" value="users">

                      <TableHeader displayRowCheckbox={false}>
                        <TableRow>
                          <TableHeaderColumn>ID</TableHeaderColumn>
                          <TableHeaderColumn>First Name</TableHeaderColumn>
                          <TableHeaderColumn>Last Name</TableHeaderColumn>
                          <TableHeaderColumn>Username</TableHeaderColumn>
                          <TableHeaderColumn>Role</TableHeaderColumn>
                          <TableHeaderColumn>Email</TableHeaderColumn>
                          <TableHeaderColumn>Delete</TableHeaderColumn>
                        </TableRow>
                      </TableHeader>
                      <TableBody displayRowCheckbox={false}>
                        {this.renderTable(users)}
                      </TableBody>

                      <Paginate
                        pageCount={users.users.paginationMeta.page_count}
                        page={this.state.user_page}
                        handlePageChange={this.handleUserPageChange}
                      />

                </Tab>
                <Tab label="Manage Documents" value="docs">

                    <TableHeader displayRowCheckbox={false}>
                      <TableRow>
                        <TableHeaderColumn>ID</TableHeaderColumn>
                        <TableHeaderColumn>Title</TableHeaderColumn>
                        <TableHeaderColumn>Content</TableHeaderColumn>
                        <TableHeaderColumn>Access Level</TableHeaderColumn>
                        <TableHeaderColumn>Author</TableHeaderColumn>
                        <TableHeaderColumn>Delete</TableHeaderColumn>
                      </TableRow>
                    </TableHeader>
                    <TableBody displayRowCheckbox={false}>
                      {this.renderDocuments(this.props.docs.allDocuments)}
                    </TableBody>

                    <Paginate
                      pageCount={allDocuments.paginationMeta.page_count}
                      page={this.state.doc_page}
                      handlePageChange={this.handleDocPageChange}
                    />

                </Tab>
              </Tabs>

          :
          ''
        }

    );
  }
}

export default ManageUser;
<|endoftext|>