<commit_before>/** @jsx React.DOM */

var Table = React.createClass({displayName: 'Table',
  propTypes: {
    data: React.PropTypes.array,
    search_placeholder: React.PropTypes.string,
    columns: React.PropTypes.array,
    filters: React.PropTypes.array, // Optional: pass null
    filter_type: React.PropTypes.bool // True for select filter, falsy for simple
  },
  getInitialState: function() {
    var first_sortable_column = this.props.columns.filter(function(col) {
      return col.sortable == true;
    })[0].id;

    var first_filter_name = this.props.filters ? this.props.filters[0].name : null;
    var first_filter_func = this.props.filters ? this.props.filters[0].func : null;

    return {
      filter: first_filter_name,
      filter_func: first_filter_func,
      sort_column: first_sortable_column,
      sort_direction: 'asc'
    }
  },
  // A filter was clicked. Adjust state accordingly.
  synchronizeFilter: function(filter) {
    var filter_func = this.props.filters.filter(function(fltr) {
        return fltr.name == filter;
      })[0].func;

    this.setState({
      filter: filter,
      filter_func: filter_func
    });
  },
  // Search input changed. Adjust state accordingly.
  synchronizeSearchInput: function(search_text) {
    this.setState({
      search_text: search_text.toLowerCase()
    });
  },
  // Header col was clicked. Adjust state accordingly.
  synchronizeHeaderColumn: function(sort_column, sort_direction) {
    this.setState({
      sort_column: sort_column,
      sort_direction: sort_direction
    });
  },
  render: function() {
    return (
      React.DOM.div(null,
        TableFilter( {filters:this.props.filters,
          current_filter:this.state.filter,
          onFilterChange:this.synchronizeFilter,
          data:this.props.data,
          filter_type:this.props.filter_type}
        ),
        TableSearch( {onSearchInputChange:this.synchronizeSearchInput,
          placeholder:this.props.search_placeholder} ),
        React.DOM.table( {className:"table"},
          TableHeader( {columns:this.props.columns,
            sort_column:this.state.sort_column,
            sort_direction:this.state.sort_direction,
            onHeaderColumnChange:this.synchronizeHeaderColumn} ),
          TableRows( {columns:this.props.columns,
                     data:this.props.data,
                     state:this.state} )
        )
      )
    );
  }
});

TableSearch = React.createClass({displayName: 'TableSearch',
  // Tells parent that the search box changed.
  // Consider using event.target.value instead?
  searchInputChanged: function() {
    this.props.onSearchInputChange(this.refs.searchText.getDOMNode().value);
  },
  render: function() {
    return (
      React.DOM.input(
        {type:"text",
        placeholder:this.props.placeholder,
        value:this.props.search_text,
        ref:"searchText",
        onChange:this.searchInputChanged} )
    );
  }
});

TableFilter = React.createClass({displayName: 'TableFilter',
  propTypes: {
      filters: React.PropTypes.array,
      current_filter: React.PropTypes.string,
      data: React.PropTypes.array,
      onFilterChange: React.PropTypes.func,
      filter_type: React.PropTypes.bool
   },
   render: function() {
     if (this.props.filters) {
       if (this.props.filter_type) {
         return (SelectTableFilter( {filters:this.props.filters,
           current_filter:this.props.current_filter,
           onFilterChange:this.props.onFilterChange} ));
       } else {
         return (SimpleTableFilter( {filters:this.props.filters,
           current_filter:this.props.current_filter,
           data:this.props.data,
           onFilterChange:this.props.onFilterChange}));
       }
     } else {
       return (React.DOM.div(null));
     }
   }
});

SimpleTableFilter = React.createClass({displayName: 'SimpleTableFilter',
  propTypes: {
    filters: React.PropTypes.array,
    current_filter: React.PropTypes.string,
    data: React.PropTypes.array,
    onFilterChange: React.PropTypes.func
  },
  // Tells parent that filter changed and to adjust accordingly.
  filterClicked: function(event) {
    this.props.onFilterChange(event.currentTarget.id);
  },
  render: function() {
    var filters_dom = [];

    for (var i = 0; i < this.props.filters.length; i++) {
      // Get number of elements that pass filter
      var number = this.props.data.filter(this.props.filters[i].func).length;
      var fltr =
        (this.props.current_filter == this.props.filters[i].name ?
         React.DOM.span( {key:this.props.filters[i].name},
           this.props.filters[i].text, " (",number,")"
           ) :
          React.DOM.a( {key:this.props.filters[i].name,
            id:this.props.filters[i].name,
            onClick:this.filterClicked},
            this.props.filters[i].text, " (",number,")"
          ));
      filters_dom.push(fltr);
      filters_dom.push(' ');
    }
    return (
      React.DOM.div(null,
        filters_dom
      )
    );
  }
});

SelectTableFilter = React.createClass({displayName: 'SelectTableFilter',
  propTypes: {
    filters: React.PropTypes.array,
    current_filter: React.PropTypes.string,
    onFilterChange: React.PropTypes.func
  },
  // Tells parent that filter changed and to adjust accordingly.
  filterChanged: function(event) {
    this.props.onFilterChange(event.currentTarget.value);
  },
  render: function() {
    var filters_dom = [];
    for (var i = 0; i < this.props.filters.length; i++) {
      var filter = React.DOM.option( {value:this.props.filters[i].name}, this.props.filters[i].text)
      filters_dom.push(filter);
    }
    return (
      React.DOM.select( {value:this.current_filter,
      onChange:this.filterChanged}, filters_dom)
    );
  }
});

TableHeader = React.createClass({displayName: 'TableHeader',
  propTypes: {
    onHeaderColumnChange: React.PropTypes.func
  },
  headerColumnClicked: function(event) {
    if (event.currentTarget.id == this.props.sort_column) {
      var new_direction = (this.props.sort_direction == 'asc' ? 'desc' : 'asc');
      this.props.onHeaderColumnChange(event.currentTarget.id, new_direction);
    } else {
      this.props.onHeaderColumnChange(event.currentTarget.id, 'asc');
    }
  },
  render: function() {
    // Create the header columns, in proper <th>'s and stuff.
    var header_columns = this.props.columns.map(function(column) {
      if (column.sortable == true) {
        var arrow_indicator = '';
        var clss = 'sortable';
        if (this.props.sort_column == column.id) {
          if (this.props.sort_direction == 'asc') {
            arrow_indicator = ' ▲';
            clss += ' asc';
          } else {
            arrow_indicator = ' ▼';
            clss += ' desc';
          }
        }
        return React.DOM.th( {key:column.id, id:column.id, className:clss,
          onClick:this.headerColumnClicked}, React.DOM.span(null,
          [column.content, arrow_indicator]))
      }
      return React.DOM.th( {key:column.id, id:column.id}, column.content)
    }.bind(this));

    return (
      React.DOM.thead(null,
        React.DOM.tr(null,
          header_columns
        )
      )
    );
  }
});

// rows
TableRows = React.createClass({displayName: 'TableRows',
  propTypes: {
    columns: React.PropTypes.array,
    data: React.PropTypes.array,
    state: React.PropTypes.object
  },

  render: function() {
    var searchables = this.props.columns.filter(function(col) {
      return col.searchable == true;
    }).map(function(col) {
      return col.id;
    });

    var filtered_data = filter_data(this.props.data,
                                    this.props.state.filter_func);

    var searched_data = search_data(filtered_data,
                                    searchables,
                                    this.props.state.search_text);

    var sorted_data = sort_by_column(searched_data,
                                     this.props.state.sort_column,
                                     this.props.state.sort_direction);

    // create rows
    // consider instead of recreating array each time, just hiding the rows.
    var rows = [];
    for (var i = 0; i < sorted_data.length; i++) {
      rows.push(
        TableRow( {key:sorted_data[i].id,
          row_object:sorted_data[i],
          columns:this.props.columns})
      );
    }

    return (
      React.DOM.tbody(null,
        rows
      )
    );

  }
});

//single row.
TableRow = React.createClass({displayName: 'TableRow',
  propTypes: {
    row_object: React.PropTypes.object,
    columns: React.PropTypes.array
  },
  render: function() {
    cells = [];

    // go through object and get data into table cells
    for (var i = 0; i < this.props.columns.length; i++) {
      var key = this.props.columns[i].id;
      cells.push(
        React.DOM.td( {key:key},
          this.props.row_object[key]
        )
      );
    }
    return (
      React.DOM.tr( {id:this.props.row_object.id},
        cells
      )
    );
  }
});

function filter_data(data, filter_func) {
  if (filter_func) {
    return data.filter(filter_func);
  } else {
    return data;
  }
}

function search_data(data, searchables, search_text) {
  if (search_text) {
    return data.filter(function(datum) {
      for (var i = 0; i < searchables.length; i++) {
        if (datum[searchables[i]].toLowerCase().indexOf(search_text) != -1) {
          return true;
        }
      }
      return false;
    });
  } else {
    return data;
  }
}

function sort_by_column(data, column, direction) {
  function makeSortable(a)
  {
    if (typeof a == 'string') {
      return a.toLowerCase().replace(' ', '');
    } else {
      return a;
    }
  }
  // sorts column id
  var r = data.sort(function(a, b) {
    if (makeSortable(a[column]) > makeSortable(b[column])) {
      return 1;
    } else if (makeSortable(b[column]) > makeSortable(a[column])) {
      return -1;
    }
    return 0;
  });
  // flips order if direction descending.
  if (direction == 'desc') r.reverse();

  return r;
}
<commit_msg>Add support for searching in component innerhtml<commit_after>/** @jsx React.DOM */

var Table = React.createClass({displayName: 'Table',
  propTypes: {
    data: React.PropTypes.array,
    search_placeholder: React.PropTypes.string,
    columns: React.PropTypes.array,
    filters: React.PropTypes.array, // Optional: pass null
    filter_type: React.PropTypes.bool // True for select filter, falsy for simple
  },
  getInitialState: function() {
    var first_sortable_column = this.props.columns.filter(function(col) {
      return col.sortable == true;
    })[0].id;

    var first_filter_name = this.props.filters ? this.props.filters[0].name : null;
    var first_filter_func = this.props.filters ? this.props.filters[0].func : null;

    return {
      filter: first_filter_name,
      filter_func: first_filter_func,
      sort_column: first_sortable_column,
      sort_direction: 'asc'
    }
  },
  // A filter was clicked. Adjust state accordingly.
  synchronizeFilter: function(filter) {
    var filter_func = this.props.filters.filter(function(fltr) {
        return fltr.name == filter;
      })[0].func;

    this.setState({
      filter: filter,
      filter_func: filter_func
    });
  },
  // Search input changed. Adjust state accordingly.
  synchronizeSearchInput: function(search_text) {
    this.setState({
      search_text: search_text.toLowerCase()
    });
  },
  // Header col was clicked. Adjust state accordingly.
  synchronizeHeaderColumn: function(sort_column, sort_direction) {
    this.setState({
      sort_column: sort_column,
      sort_direction: sort_direction
    });
  },
  render: function() {
    return (
      React.DOM.div(null,
        TableFilter( {filters:this.props.filters,
          current_filter:this.state.filter,
          onFilterChange:this.synchronizeFilter,
          data:this.props.data,
          filter_type:this.props.filter_type}
        ),
        TableSearch( {onSearchInputChange:this.synchronizeSearchInput,
          placeholder:this.props.search_placeholder} ),
        React.DOM.table( {className:"table"},
          TableHeader( {columns:this.props.columns,
            sort_column:this.state.sort_column,
            sort_direction:this.state.sort_direction,
            onHeaderColumnChange:this.synchronizeHeaderColumn} ),
          TableRows( {columns:this.props.columns,
                     data:this.props.data,
                     state:this.state} )
        )
      )
    );
  }
});

TableSearch = React.createClass({displayName: 'TableSearch',
  // Tells parent that the search box changed.
  // Consider using event.target.value instead?
  searchInputChanged: function() {
    this.props.onSearchInputChange(this.refs.searchText.getDOMNode().value);
  },
  render: function() {
    return (
      React.DOM.input(
        {type:"text",
        placeholder:this.props.placeholder,
        value:this.props.search_text,
        ref:"searchText",
        onChange:this.searchInputChanged} )
    );
  }
});

TableFilter = React.createClass({displayName: 'TableFilter',
  propTypes: {
      filters: React.PropTypes.array,
      current_filter: React.PropTypes.string,
      data: React.PropTypes.array,
      onFilterChange: React.PropTypes.func,
      filter_type: React.PropTypes.bool
   },
   render: function() {
     if (this.props.filters) {
       if (this.props.filter_type) {
         return (SelectTableFilter( {filters:this.props.filters,
           current_filter:this.props.current_filter,
           onFilterChange:this.props.onFilterChange} ));
       } else {
         return (SimpleTableFilter( {filters:this.props.filters,
           current_filter:this.props.current_filter,
           data:this.props.data,
           onFilterChange:this.props.onFilterChange}));
       }
     } else {
       return (React.DOM.div(null));
     }
   }
});

SimpleTableFilter = React.createClass({displayName: 'SimpleTableFilter',
  propTypes: {
    filters: React.PropTypes.array,
    current_filter: React.PropTypes.string,
    data: React.PropTypes.array,
    onFilterChange: React.PropTypes.func
  },
  // Tells parent that filter changed and to adjust accordingly.
  filterClicked: function(event) {
    this.props.onFilterChange(event.currentTarget.id);
  },
  render: function() {
    var filters_dom = [];

    for (var i = 0; i < this.props.filters.length; i++) {
      // Get number of elements that pass filter
      var number = this.props.data.filter(this.props.filters[i].func).length;
      var fltr =
        (this.props.current_filter == this.props.filters[i].name ?
         React.DOM.span( {key:this.props.filters[i].name},
           this.props.filters[i].text, " (",number,")"
           ) :
          React.DOM.a( {key:this.props.filters[i].name,
            id:this.props.filters[i].name,
            onClick:this.filterClicked},
            this.props.filters[i].text, " (",number,")"
          ));
      filters_dom.push(fltr);
      filters_dom.push(' ');
    }
    return (
      React.DOM.div(null,
        filters_dom
      )
    );
  }
});

SelectTableFilter = React.createClass({displayName: 'SelectTableFilter',
  propTypes: {
    filters: React.PropTypes.array,
    current_filter: React.PropTypes.string,
    onFilterChange: React.PropTypes.func
  },
  // Tells parent that filter changed and to adjust accordingly.
  filterChanged: function(event) {
    this.props.onFilterChange(event.currentTarget.value);
  },
  render: function() {
    var filters_dom = [];
    for (var i = 0; i < this.props.filters.length; i++) {
      var filter = React.DOM.option( {value:this.props.filters[i].name}, this.props.filters[i].text)
      filters_dom.push(filter);
    }
    return (
      React.DOM.select( {value:this.current_filter,
      onChange:this.filterChanged}, filters_dom)
    );
  }
});

TableHeader = React.createClass({displayName: 'TableHeader',
  propTypes: {
    onHeaderColumnChange: React.PropTypes.func
  },
  headerColumnClicked: function(event) {
    if (event.currentTarget.id == this.props.sort_column) {
      var new_direction = (this.props.sort_direction == 'asc' ? 'desc' : 'asc');
      this.props.onHeaderColumnChange(event.currentTarget.id, new_direction);
    } else {
      this.props.onHeaderColumnChange(event.currentTarget.id, 'asc');
    }
  },
  render: function() {
    // Create the header columns, in proper <th>'s and stuff.
    var header_columns = this.props.columns.map(function(column) {
      if (column.sortable == true) {
        var arrow_indicator = '';
        var clss = 'sortable';
        if (this.props.sort_column == column.id) {
          if (this.props.sort_direction == 'asc') {
            arrow_indicator = ' ▲';
            clss += ' asc';
          } else {
            arrow_indicator = ' ▼';
            clss += ' desc';
          }
        }
        return React.DOM.th( {key:column.id, id:column.id, className:clss,
          onClick:this.headerColumnClicked}, React.DOM.span(null,
          [column.content, arrow_indicator]))
      }
      return React.DOM.th( {key:column.id, id:column.id}, column.content)
    }.bind(this));

    return (
      React.DOM.thead(null,
        React.DOM.tr(null,
          header_columns
        )
      )
    );
  }
});

// rows
TableRows = React.createClass({displayName: 'TableRows',
  propTypes: {
    columns: React.PropTypes.array,
    data: React.PropTypes.array,
    state: React.PropTypes.object
  },

  render: function() {
    var searchables = this.props.columns.filter(function(col) {
      return col.searchable == true;
    }).map(function(col) {
      return col.id;
    });

    var filtered_data = filter_data(this.props.data,
                                    this.props.state.filter_func);

    var searched_data = search_data(filtered_data,
                                    searchables,
                                    this.props.state.search_text);

    var sorted_data = sort_by_column(searched_data,
                                     this.props.state.sort_column,
                                     this.props.state.sort_direction);

    // create rows
    // consider instead of recreating array each time, just hiding the rows.
    var rows = [];
    for (var i = 0; i < sorted_data.length; i++) {
      rows.push(
        TableRow( {key:sorted_data[i].id,
          row_object:sorted_data[i],
          columns:this.props.columns})
      );
    }

    return (
      React.DOM.tbody(null,
        rows
      )
    );

  }
});

//single row.
TableRow = React.createClass({displayName: 'TableRow',
  propTypes: {
    row_object: React.PropTypes.object,
    columns: React.PropTypes.array
  },
  render: function() {
    cells = [];

    // go through object and get data into table cells
    for (var i = 0; i < this.props.columns.length; i++) {
      var key = this.props.columns[i].id;
      cells.push(
        React.DOM.td( {key:key},
          this.props.row_object[key]
        )
      );
    }
    return (
      React.DOM.tr( {id:this.props.row_object.id},
        cells
      )
    );
  }
});

function filter_data(data, filter_func) {
  if (filter_func) {
    return data.filter(filter_func);
  } else {
    return data;
  }
}

function search_data(data, searchables, search_text) {
  if (search_text) {
    return data.filter(function(datum) {
      for (var i = 0; i < searchables.length; i++) {
        if (datum[searchables[i]].hasOwnProperty('props')) {
          // is a React Component- need to get innerHTML
          if (datum[searchables[i]].props.dangerouslySetInnerHTML.__html.toLowerCase().indexOf(search_text) != -1) {
            return true;
          }
          return false;
        } else {
          if (datum[searchables[i]].toLowerCase().indexOf(search_text) != -1) {
            return true;
          }
        }
        return false;
      }
    });
  } else {
    return data;
  }
}

function sort_by_column(data, column, direction) {
  function makeSortable(a)
  {
    if (typeof a == 'string') {
      return a.toLowerCase().replace(' ', '');
    } else {
      return a;
    }
  }
  // sorts column id
  var r = data.sort(function(a, b) {
    if (makeSortable(a[column]) > makeSortable(b[column])) {
      return 1;
    } else if (makeSortable(b[column]) > makeSortable(a[column])) {
      return -1;
    }
    return 0;
  });
  // flips order if direction descending.
  if (direction == 'desc') r.reverse();

  return r;
}
<|endoftext|>


<commit_before>/**
 * The Slide view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps',
  'enquire',
  'handlebars',
  'slick'
], function($,Backbone, _,mps, enquire, Handlebars, slick) {

  'use strict';

  // SLIDER
  var SlideView = Backbone.View.extend({

    el: '.main-slider',

    events: {
      'click #get-started' : 'getStarted',
      'click #go-to-apps' : 'goToApps',
      'click .gotomap' : 'gotoMap'
    },

    initialize: function() {
      //Init
      this.$getStarted = $('#get-started');

      //Inits
      this.slickSlider();
    },

    slickSlider: function(){
      //INIT
      $('.main-slider-viewport').slick({
        infinite: true,
        speed: 500,
        // autoplay: true,
        autoplaySpeed: 3000,
        slide: 'li',
        fade: true,
        cssEase: 'linear',
        dots: true,
        pauseOnHover: false,
        arrows: false,

        responsive: [
          {
            breakpoint: 850,
            speed: 250,
            settings: {
              fade: false,
              cssEase: 'ease-out'
            }
          }
        ]
      });

    },

    getStarted: function(e){
      e.stopPropagation();
      $(e.currentTarget).toggleClass('active');
    },

    /**
     * Closes submenu tooltip
     * Check the click target is not the dialog itself.
     *
     * @param  {Object} e Event
     */
    _onHtmlClick: function(e) {
      if (!$(e.target).hasClass('submenu-tooltip') && this.$getStarted.hasClass('active')) {
        this.$getStarted.removeClass('active');
      }
    },

    goToApps: function(e){
      e.preventDefault();
      var posY = $($(e.currentTarget).attr('href')).offset().top;
      $('html,body').animate({scrollTop: posY},500);
    },

    gotoMap: function(e) {
      e.preventDefault();
      e.stopPropagation();

      var $target = $(e.target);

      if (!$(e.target).hasClass('gotomap')) {
        $target = $(e.target).parent();
      }

      if ($target.data('dialog')) {
        var dialog = JSON.stringify(
        {
          "display": true,
          "type" : $target.data('dialog')
        });

        sessionStorage.setItem('DIALOG', dialog);
      }
      ga('send', 'event', 'Get Started', 'Click', $target.data('ga'));
      window.setTimeout(function(){location.assign($target.attr('href'));20});
    }

  });

  return SlideView;

});
<commit_msg>Enabled slider autoplay again<commit_after>/**
 * The Slide view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps',
  'enquire',
  'handlebars',
  'slick'
], function($,Backbone, _,mps, enquire, Handlebars, slick) {

  'use strict';

  // SLIDER
  var SlideView = Backbone.View.extend({

    el: '.main-slider',

    events: {
      'click #get-started' : 'getStarted',
      'click #go-to-apps' : 'goToApps',
      'click .gotomap' : 'gotoMap'
    },

    initialize: function() {
      //Init
      this.$getStarted = $('#get-started');

      //Inits
      this.slickSlider();
    },

    slickSlider: function(){
      //INIT
      $('.main-slider-viewport').slick({
        infinite: true,
        speed: 500,
        autoplay: true,
        autoplaySpeed: 3000,
        slide: 'li',
        fade: true,
        cssEase: 'linear',
        dots: true,
        pauseOnHover: false,
        arrows: false,

        responsive: [
          {
            breakpoint: 850,
            speed: 250,
            settings: {
              fade: false,
              cssEase: 'ease-out'
            }
          }
        ]
      });

    },

    getStarted: function(e){
      e.stopPropagation();
      $(e.currentTarget).toggleClass('active');
    },

    /**
     * Closes submenu tooltip
     * Check the click target is not the dialog itself.
     *
     * @param  {Object} e Event
     */
    _onHtmlClick: function(e) {
      if (!$(e.target).hasClass('submenu-tooltip') && this.$getStarted.hasClass('active')) {
        this.$getStarted.removeClass('active');
      }
    },

    goToApps: function(e){
      e.preventDefault();
      var posY = $($(e.currentTarget).attr('href')).offset().top;
      $('html,body').animate({scrollTop: posY},500);
    },

    gotoMap: function(e) {
      e.preventDefault();
      e.stopPropagation();

      var $target = $(e.target);

      if (!$(e.target).hasClass('gotomap')) {
        $target = $(e.target).parent();
      }

      if ($target.data('dialog')) {
        var dialog = JSON.stringify(
        {
          "display": true,
          "type" : $target.data('dialog')
        });

        sessionStorage.setItem('DIALOG', dialog);
      }
      ga('send', 'event', 'Get Started', 'Click', $target.data('ga'));
      window.setTimeout(function(){location.assign($target.attr('href'));20});
    }

  });

  return SlideView;

});
<|endoftext|>


<commit_before>angular.module('ocWebGui.queue', ['ocWebGui.queue.service', 'ui.router', 'ocWebGui.shared.time', 'nvd3'])
  .config(function ($stateProvider) {
    $stateProvider
      .state('queue', {
        url: '/queue',
        templateUrl: 'queue/_queue.html',
        controller: 'QueueController',
        controllerAs: 'queue'
      });
  })
  .controller('QueueController', function ($interval, $scope, Queue, $http) {
    var vm = this;

    vm.options = {
      chart: {
        type: 'linePlusBarChart',
        height: 360,
        margin: {
          top: 30,
          right: 40,
          bottom: 60,
          left: 40
        },
        x: function (d) { return d.hour; },
        y: function (d) { return d.calls; },
        bars: {
          forceY: [0,50]
        },
        lines: {
          forceY: [0,50]
        },
        xAxis: {
          tickFormat: function (d) {
            return d3.format(',f')(d);
          },
          axisLabel: 'Kellonaika',
          showMaxMin: true
        },
        y1Axis: {
          tickValues: [0, 10, 20, 30, 40, 50],
        },
        y2Axis: {
          ticks: 5
        }
      }
    };
    vm.data = [{
      'key': 'Puheluita tunnissa',
      'bar': true,
      'color': '#000000',
      'values': []
    }, {
      'key': 'bar',
      'color': '#ff0000',
      'values': []
    }];

    function fetchStats() {
      $http.get('contacts/stats.json').then(function (response) {
        var data = response.data;
        var values = data.calls_by_hour
          .map(function (calls, hour) { return { hour: hour, calls: calls }; })
          // .filter(function (item) { return item.calls !== 0; });
          .filter(function (item) { return item.hour >= 8 && item.hour <= 18; })
          ;
        vm.stats = data;
        vm.data[0].values = values;
      });
    }

    vm.message = 'Jono';

    vm.queue = [];

    vm.date = new Date();

    function fetchData() {
      Queue.query(function (queue) {
        vm.queue = queue.filter(function (queuer) {
          return queuer.language !== 'Unknown';
        });
      });
      // Also update date/time
      vm.date = new Date();
    }

    var fetchDataInterval = $interval(fetchData, 5 * 1000);
    var fetchStatsInterval = $interval(fetchStats, 5 * 60 * 1000);
    $scope.$on('$destroy', function () {
      $interval.cancel(fetchDataInterval);
      $interval.cancel(fetchStatsInterval);
    });

    fetchData();
    fetchStats();

    // mock data for testing css
    // vm.queue = [
    //   { line: 135, language: 'Fin', time_in_queue: 360 },
    //   { line: 137, language: 'Fin', time_in_queue: 123 },
    //   { line: 125, language: 'Eng', time_in_queue: 123 },
    //   { line: 137, language: 'Fin', time_in_queue: 123 },
    //   { line: 133, language: 'Swe', time_in_queue: 53  },
    //   { line: 131, language: 'Eng', time_in_queue: 123 },
    //   { line: 121, language: 'Eng', time_in_queue: 214 }
    // ];
  });
<commit_msg>fix lint stuff<commit_after>angular.module('ocWebGui.queue', ['ocWebGui.queue.service', 'ui.router', 'ocWebGui.shared.time', 'nvd3'])
  .config(function ($stateProvider) {
    $stateProvider
      .state('queue', {
        url: '/queue',
        templateUrl: 'queue/_queue.html',
        controller: 'QueueController',
        controllerAs: 'queue'
      });
  })
  .controller('QueueController', function ($interval, $scope, Queue, $http) {
    var vm = this;

    vm.options = {
      chart: {
        type: 'linePlusBarChart',
        height: 360,
        margin: {
          top: 30,
          right: 40,
          bottom: 60,
          left: 40
        },
        x: function (d) { return d.hour; },
        y: function (d) { return d.calls; },
        bars: {
          forceY: [0, 50]
        },
        lines: {
          forceY: [0, 50]
        },
        xAxis: {
          tickFormat: function (d) {
            return d3.format(',f')(d);
          },
          axisLabel: 'Kellonaika',
          showMaxMin: true
        },
        y1Axis: {
          tickValues: [0, 10, 20, 30, 40, 50]
        },
        y2Axis: {
          ticks: 5
        }
      }
    };
    vm.data = [{
      'key': 'Puheluita tunnissa',
      'bar': true,
      'color': '#000000',
      'values': []
    }, {
      'key': 'bar',
      'color': '#ff0000',
      'values': []
    }];

    function fetchStats() {
      $http.get('contacts/stats.json').then(function (response) {
        var data = response.data;
        var values = data.calls_by_hour
          .map(function (calls, hour) { return { hour: hour, calls: calls }; })
          // .filter(function (item) { return item.calls !== 0; });
          .filter(function (item) { return item.hour >= 8 && item.hour <= 18; })
          ;
        vm.stats = data;
        vm.data[0].values = values;
      });
    }

    vm.message = 'Jono';

    vm.queue = [];

    vm.date = new Date();

    function fetchData() {
      Queue.query(function (queue) {
        vm.queue = queue.filter(function (queuer) {
          return queuer.language !== 'Unknown';
        });
      });
      // Also update date/time
      vm.date = new Date();
    }

    var fetchDataInterval = $interval(fetchData, 5 * 1000);
    var fetchStatsInterval = $interval(fetchStats, 5 * 60 * 1000);
    $scope.$on('$destroy', function () {
      $interval.cancel(fetchDataInterval);
      $interval.cancel(fetchStatsInterval);
    });

    fetchData();
    fetchStats();

    // mock data for testing css
    // vm.queue = [
    //   { line: 135, language: 'Fin', time_in_queue: 360 },
    //   { line: 137, language: 'Fin', time_in_queue: 123 },
    //   { line: 125, language: 'Eng', time_in_queue: 123 },
    //   { line: 137, language: 'Fin', time_in_queue: 123 },
    //   { line: 133, language: 'Swe', time_in_queue: 53  },
    //   { line: 131, language: 'Eng', time_in_queue: 123 },
    //   { line: 121, language: 'Eng', time_in_queue: 214 }
    // ];
  });
<|endoftext|>


<commit_before>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import config from '../config';

const defaultState = {
  fetchedParams: false,
  fetchingParams: false,
  paramError: null,
  parameters: null,
};

export const ParameterContext = React.createContext([{}, () => {}]);

export function ParameterProvider(props) {
  const [
    { fetchedParams, fetchingParams, paramError, parameters },
    setState,
  ] = useState(defaultState);

  useEffect(() => {
    const fetchData = () => {
      setState(state => ({ ...state, fetchingParams: true, paramError: null }));

      fetch(`${config.api}/parameters`)
        .then(response => {
          if (response.status >= 400) {
            throw new paramError('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              parameters: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              paramError: e,
            }));
          }
        );
    };

    fetchData();

    return () => {
      setState(defaultState);
    };
  }, []);

  const isCore = function (activeParameterId) {
    return parameters && activeParameterId
      ? parameters.find(p => p.id === activeParameterId).isCore
      : null;
  };

  return (
    <ParameterContext.Provider
      value={{ fetchedParams, fetchingParams, paramError, parameters, isCore }}
    >
      {props.children}
    </ParameterContext.Provider>
  );
}
ParameterProvider.propTypes = {
  children: PropTypes.node,
};
<commit_msg>change fallback<commit_after>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import config from '../config';

const defaultState = {
  fetchedParams: false,
  fetchingParams: false,
  paramError: null,
  parameters: null,
};

export const ParameterContext = React.createContext([{}, () => {}]);

export function ParameterProvider(props) {
  const [
    { fetchedParams, fetchingParams, paramError, parameters },
    setState,
  ] = useState(defaultState);

  useEffect(() => {
    const fetchData = () => {
      setState(state => ({ ...state, fetchingParams: true, paramError: null }));

      fetch(`${config.api}/parameters`)
        .then(response => {
          if (response.status >= 400) {
            throw new paramError('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              parameters: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              paramError: e,
            }));
          }
        );
    };

    fetchData();

    return () => {
      setState(defaultState);
    };
  }, []);

  const isCore = function (activeParameterId) {
    return parameters && activeParameterId
      ? parameters.find(p => p.id === activeParameterId).isCore
      : false;
  };

  return (
    <ParameterContext.Provider
      value={{ fetchedParams, fetchingParams, paramError, parameters, isCore }}
    >
      {props.children}
    </ParameterContext.Provider>
  );
}
ParameterProvider.propTypes = {
  children: PropTypes.node,
};
<|endoftext|>


<commit_before>/**
 * Poster v0.1.0
 * A React webapp to list upcoming movies and maintain a watchlist, powered by TMDb
 *
 * Author: Kushal Pandya <kushalspandya@gmail.com> (https://doublslash.com)
 * Date: 02 June, 2016
 * License: MIT
 *
 * Navbar Links Container
 */

import React from "react";

import NavbarLinkItem from "./NavbarLinkItem";

export default
class NavbarLinks extends React.Component {
    constructor() {
        super();
    }

    render() {
        return (

                <NavbarLinkItem linkTitle="Upcoming Movies"/>
                <NavbarLinkItem linkTitle="Watchlist"/>

        );
    }
}
<commit_msg>Added "Top 20" link for showing top rated movies.<commit_after>/**
 * Poster v0.1.0
 * A React webapp to list upcoming movies and maintain a watchlist, powered by TMDb
 *
 * Author: Kushal Pandya <kushalspandya@gmail.com> (https://doublslash.com)
 * Date: 02 June, 2016
 * License: MIT
 *
 * Navbar Links Container
 */

import React from "react";

import NavbarLinkItem from "./NavbarLinkItem";

export default
class NavbarLinks extends React.Component {
    constructor() {
        super();
    }

    render() {
        return (

                <NavbarLinkItem linkTitle="Top 20"/>
                <NavbarLinkItem linkTitle="Upcoming Movies"/>
                <NavbarLinkItem linkTitle="Watchlist"/>

        );
    }
}
<|endoftext|>


<commit_before>"use strict";

angular.module('arethusa.core').directive('keysToScreen', [
  '$timeout',
  'configurator',
  'keyCapture',
  function($timeout, configurator, keyCapture) {
    return {
      restrict: 'A',
      scope: {},
      link: function(scope, element, attrs) {
        var conf = configurator.configurationFor('main');

        function Key(key) {
          this.str = key === "PLUS" ? '+' : key;
          this.joiner = key === 'PLUS';
        }

        function parseKey(key) {
          // Producing new objects here in purpose, so that angular
          // has to redo the html element in the ngRepeat - we can
          // benefit from renewing the nice css animations then.
          scope.actions = arethusaUtil.map(keyCapture.keyList[key], function(el) {
            return { str: el };
          });

          var keys, elements;
          // This looks a bit ugly, but a regular + might also be a
          // valid keybinding - we therefore use an unambigous value here.
          //
          // Key can also be a number - we therefore typecast.
          keys = (key + '').replace(/-/g, '-PLUS-').split();
          elements = arethusaUtil.inject([], keys, function(memo, key) {
            if (key.match(/^[A-Z]$/)) {
              arethusaUtil.pushAll(memo, ['shift', 'PLUS', key.toLowerCase()]);
            } else {
              memo.push(key);
            }
          });
          return arethusaUtil.map(elements, function(el) { return new Key(el); });
        }

        // This isn't updated know - it's either activated on startup, or
        // it isn't.
        if (conf.showKeys) {
          scope.keys = [];
          scope.actions = [];

          var clear, override, readyToOverride;
          scope.$on('keyCaptureLaunched', function(event, key) {
            var keys = parseKey(key);
            scope.$apply(function() {
              if (readyToOverride) {
                scope.keys = keys;
                readyToOverride = false;
              } else {
                arethusaUtil.pushAll(scope.keys, keys);
              }
            });

            if (override) $timeout.cancel(override);
            if (clear) $timeout.cancel(clear);

            override = $timeout(function() {
              readyToOverride = true;
            }, 1500);

            clear = $timeout(function() {
              scope.keys = [];
              scope.actions = [];
            }, 3200);
          });
        }

      },
      templateUrl: 'templates/arethusa.core/keys_to_screen.html'
    };
  }
]);
<commit_msg>More refactoring in keysToScreen<commit_after>"use strict";

angular.module('arethusa.core').directive('keysToScreen', [
  '$timeout',
  'configurator',
  'keyCapture',
  function($timeout, configurator, keyCapture) {
    return {
      restrict: 'A',
      scope: {},
      link: function(scope, element, attrs) {
        var conf = configurator.configurationFor('main');

        function Key(key) {
          this.str = key === "PLUS" ? '+' : key;
          this.joiner = key === 'PLUS';
        }

        function parseKey(key) {
          // Producing new objects here in purpose, so that angular
          // has to redo the html element in the ngRepeat - we can
          // benefit from renewing the nice css animations then.
          //
          // We need || [] in case we encounter a numeric modifier.
          scope.actions = arethusaUtil.map(keyCapture.keyList[key] || [], function(el) {
            return { str: el };
          });

          var keys, elements;
          // This looks a bit ugly, but a regular + might also be a
          // valid keybinding - we therefore use an unambigous value here.
          //
          // Key can also be a number - we therefore typecast.
          keys = (key + '').replace(/-/g, '-PLUS-').split();
          elements = arethusaUtil.inject([], keys, function(memo, key) {
            if (key.match(/^[A-Z]$/)) {
              arethusaUtil.pushAll(memo, ['shift', 'PLUS', key.toLowerCase()]);
            } else {
              memo.push(key);
            }
          });
          return arethusaUtil.map(elements, function(el) { return new Key(el); });
        }

        // This isn't updated know - it's either activated on startup, or
        // it isn't.
        if (conf.showKeys) {
          scope.keys = [];
          scope.actions = [];

          var clear, override, readyToOverride;
          scope.$on('keyCaptureLaunched', function(event, key) {
            var keys = parseKey(key);
            scope.$apply(function() {
              if (readyToOverride) {
                scope.keys = keys;
                readyToOverride = false;
              } else {
                arethusaUtil.pushAll(scope.keys, keys);
              }
            });

            if (override) $timeout.cancel(override);
            if (clear) $timeout.cancel(clear);

            override = $timeout(function() {
              readyToOverride = true;
            }, 1500);

            clear = $timeout(function() {
              scope.keys = [];
              scope.actions = [];
            }, 3200);
          });
        }

      },
      templateUrl: 'templates/arethusa.core/keys_to_screen.html'
    };
  }
]);
<|endoftext|>


<commit_before>'use strict';

angular.module('bitPrice.price.subcentsFilter', [])

.filter('subcents', function() {
  return function(input) {
    var number = Number(input);

    if(number > 1) {
      //display value in dollars
      return '$' + number.toFixed(2);
    } else {
      //display value in cents
      return (number * 100).toFixed(4) + '¢';
    }
  };
});
<commit_msg>remove extra 0<commit_after>'use strict';

angular.module('bitPrice.price.subcentsFilter', [])

.filter('subcents', function() {
  return function(input) {
    var number = Number(input);

    if(number > 1) {
      //display value in dollars
      return '$' + number.toFixed(2);
    } else {
      //display value in cents
      return '.' + (number * 100).toFixed(4).split('.')[1] + '¢';
    }
  };
});
<|endoftext|>


<commit_before>'use strict';

(function() {
  angular.module('ncsaas')
  .controller('PaymentApproveController',
    ['ncUtils',
     'ncUtilsFlash',
     'paymentsService',
     '$state',
     '$rootScope',
     'currentStateService',
     'baseControllerClass',
     PaymentApproveController]);

  function PaymentApproveController(
    ncUtils,
    ncUtilsFlash,
    paymentsService,
    $state,
    $rootScope,
    currentStateService,
    baseControllerClass) {
    var controllerScope = this;
    var Controller = baseControllerClass.extend({
      init: function() {
        this._super();
        this.approvePayment();
      },
      approvePayment: function() {
        var qs = ncUtils.parseQueryString(ncUtils.getQueryString());
        if (!qs.paymentId || !qs.PayerID) {
          ncUtilsFlash.error('Invalid URL. Unable to parse payment details.');
          return;
        }
        paymentsService.approve({
          payment_id: qs.paymentId,
          payer_id: qs.PayerID
        }).then(function(response) {
          ncUtilsFlash.success('Payment has been processed successfully.');
          currentStateService.reloadCurrentCustomer(function() {
            $rootScope.$broadcast('customerBalance:refresh');
          });
          $state.go('home.home', {});
        });
      },
    });

    controllerScope.__proto__ = new Controller();
  }

  angular.module('ncsaas')
  .controller('PaymentCancelController',
    ['ncUtils',
     'ncUtilsFlash',
     'paymentsService',
     '$state',
     'baseControllerClass',
     PaymentCancelController]);

  function PaymentCancelController(
    ncUtils,
    ncUtilsFlash,
    paymentsService,
    $state,
    baseControllerClass) {
    var controllerScope = this;
    var Controller = baseControllerClass.extend({
      init: function() {
        this._super();
        this.cancelPayment();
      },
      cancelPayment: function() {
        var qs = ncUtils.parseQueryString(ncUtils.getQueryString());
        if (!qs.paymentId || !qs.PayerID) {
          ncUtilsFlash.error('Invalid URL. Unable to parse payment details.');
          return;
        }
        paymentsService.cancel({payment_id: qs.paymentId}).then(function(response) {
          ncUtilsFlash.success('Payment has been processed successfully.');
          $state.go('home.home', {});
        });
      },
    });

    controllerScope.__proto__ = new Controller();
  }

})();
<commit_msg>Use token for payment cancel (SAAS-1101)<commit_after>'use strict';

(function() {
  angular.module('ncsaas')
  .controller('PaymentApproveController',
    ['ncUtils',
     'ncUtilsFlash',
     'paymentsService',
     '$state',
     '$rootScope',
     'currentStateService',
     'baseControllerClass',
     PaymentApproveController]);

  function PaymentApproveController(
    ncUtils,
    ncUtilsFlash,
    paymentsService,
    $state,
    $rootScope,
    currentStateService,
    baseControllerClass) {
    var controllerScope = this;
    var Controller = baseControllerClass.extend({
      init: function() {
        this._super();
        this.approvePayment();
      },
      approvePayment: function() {
        var qs = ncUtils.parseQueryString(ncUtils.getQueryString());
        if (!qs.paymentId || !qs.PayerID) {
          ncUtilsFlash.error('Invalid URL. Unable to parse payment details.');
          return;
        }
        paymentsService.approve({
          payment_id: qs.paymentId,
          payer_id: qs.PayerID
        }).then(function(response) {
          ncUtilsFlash.success('Payment has been processed successfully.');
          currentStateService.reloadCurrentCustomer(function() {
            $rootScope.$broadcast('customerBalance:refresh');
          });
          $state.go('home.home', {});
        });
      },
    });

    controllerScope.__proto__ = new Controller();
  }

  angular.module('ncsaas')
  .controller('PaymentCancelController',
    ['ncUtils',
     'ncUtilsFlash',
     'paymentsService',
     '$state',
     'baseControllerClass',
     PaymentCancelController]);

  function PaymentCancelController(
    ncUtils,
    ncUtilsFlash,
    paymentsService,
    $state,
    baseControllerClass) {
    var controllerScope = this;
    var Controller = baseControllerClass.extend({
      init: function() {
        this._super();
        this.cancelPayment();
      },
      cancelPayment: function() {
        var qs = ncUtils.parseQueryString(ncUtils.getQueryString());
        if (!qs.token) {
          ncUtilsFlash.error('Invalid URL. Unable to parse payment details.');
          return;
        }
        paymentsService.cancel({token: qs.token}).then(function(response) {
          ncUtilsFlash.success('Payment has been processed successfully.');
          $state.go('home.home', {});
        });
      },
    });

    controllerScope.__proto__ = new Controller();
  }

})();
<|endoftext|>


<commit_before>'use strict';

(function() {
  angular.module('ncsaas')
    .controller('ServiceListController',
      ['$state', 'servicesService', 'customerPermissionsService', 'usersService', ServiceListController]);

  function ServiceListController($state, servicesService, customerPermissionsService, usersService) {
    var vm = this;

    vm.list = [];

    // search
    vm.searchInput = '';
    vm.search = search;
    vm.service = servicesService;

    vm.remove = remove;

    function activate() {
      getList();
      // init canUserAddService
      usersService.getCurrentUser().then(function(user) {
        /*jshint camelcase: false */
        if (user.is_staff) {
          vm.canUserAddService = true;
        }
        customerPermissionsService.getList({username: user.username}).then(function(permissions) {
          if (permissions.length !== 0) {
            vm.canUserAddService = (permissions[0].role === 'owner');
          }
        });
      });
    }

    function getList(filters) {
      servicesService.getList(filters).then(function(response) {
        vm.list = response;
      });
    }

    function search() {
      getList({name: vm.searchInput});
    }

    function remove(service) {
      var confirmDelete = confirm('Confirm service deletion?');
      if (confirmDelete) {
        var index = vm.list.indexOf(service);
        service.$delete(function() {
          vm.list.splice(index, 1);
        },handleServiceActionException);
      }
    }

    function handleServiceActionException(response) {
      if (response.status === 409) {
        var message = response.data.status || response.data.detail;
        alert(message);
      }
    }

    activate();

  }

})();

(function() {
  angular.module('ncsaas')
    .controller('ServiceAddController', ['servicesService', '$state',
      'currentStateService', '$rootScope', 'projectCloudMembershipsService', 'projectsService', ServiceAddController]);

  function ServiceAddController(
    servicesService, $state, currentStateService, $rootScope, projectCloudMembershipsService, projectsService) {
    var vm = this;
    vm.service = servicesService.$create();
    vm.save = save;
    vm.cancel = cancel;
    vm.projectList = {};
    vm.custumersList = {};

    function activate() {
      currentStateService.getCustomer().then(function(customer) {
        vm.service.customer = customer.url;
      });
      /*jshint camelcase: false */
      if (vm.service.auth_url || vm.service.name) {
        if (confirm('Clean all fields?')) {
          vm.service.auth_url = '';
          vm.service.name = '';
        }
      }
    }

    $rootScope.$on('currentCustomerUpdated', activate);

    function save() {
      vm.service.$save(success, error);

      function success() {
        projectsService.filterByCustomer = false;
        projectsService.getList().then(function(response) {
          for (var i = 0; response.length > i; i++) {
            projectCloudMembershipsService.addRow(response[i].url, vm.service.url);
          }
        });
        $state.go('services.list');
      }

      function error(response) {
        vm.errors = response.data;
      }
    }

    function cancel() {
      $state.go('services.list');
    }

    activate();

  }

})();

(function() {
  angular.module('ncsaas')
    .controller('ServiceDetailUpdateController',
      ['baseControllerClass', 'servicesService', '$stateParams', '$state', ServiceDetailUpdateController]);

  function ServiceDetailUpdateController(baseControllerClass, servicesService, $stateParams, $state) {
    var controllerScope = this;
    var Controller = baseControllerClass.extend({
      service: null,

      init:function() {
        this._super();
        this.activate();
      },
      activate:function() {
        var vm = this;
        servicesService.$get($stateParams.uuid).then(function(response) {
          vm.service = response;
        });
      },
      remove:function() {
        if (confirm('Are you sure you want to delete service?')) {
          this.service.$delete(
            function() {
              $state.go('services.list');
            },
            function(errors) {
              alert(errors.data.detail);
            }
          );
        }
      }
    });

    controllerScope.__proto__ = new Controller();
  }
})();<commit_msg>Add a newline<commit_after>'use strict';

(function() {
  angular.module('ncsaas')
    .controller('ServiceListController',
      ['$state', 'servicesService', 'customerPermissionsService', 'usersService', ServiceListController]);

  function ServiceListController($state, servicesService, customerPermissionsService, usersService) {
    var vm = this;

    vm.list = [];

    // search
    vm.searchInput = '';
    vm.search = search;
    vm.service = servicesService;

    vm.remove = remove;

    function activate() {
      getList();
      // init canUserAddService
      usersService.getCurrentUser().then(function(user) {
        /*jshint camelcase: false */
        if (user.is_staff) {
          vm.canUserAddService = true;
        }
        customerPermissionsService.getList({username: user.username}).then(function(permissions) {
          if (permissions.length !== 0) {
            vm.canUserAddService = (permissions[0].role === 'owner');
          }
        });
      });
    }

    function getList(filters) {
      servicesService.getList(filters).then(function(response) {
        vm.list = response;
      });
    }

    function search() {
      getList({name: vm.searchInput});
    }

    function remove(service) {
      var confirmDelete = confirm('Confirm service deletion?');
      if (confirmDelete) {
        var index = vm.list.indexOf(service);
        service.$delete(function() {
          vm.list.splice(index, 1);
        },handleServiceActionException);
      }
    }

    function handleServiceActionException(response) {
      if (response.status === 409) {
        var message = response.data.status || response.data.detail;
        alert(message);
      }
    }

    activate();

  }

})();

(function() {
  angular.module('ncsaas')
    .controller('ServiceAddController', ['servicesService', '$state',
      'currentStateService', '$rootScope', 'projectCloudMembershipsService', 'projectsService', ServiceAddController]);

  function ServiceAddController(
    servicesService, $state, currentStateService, $rootScope, projectCloudMembershipsService, projectsService) {
    var vm = this;
    vm.service = servicesService.$create();
    vm.save = save;
    vm.cancel = cancel;
    vm.projectList = {};
    vm.custumersList = {};

    function activate() {
      currentStateService.getCustomer().then(function(customer) {
        vm.service.customer = customer.url;
      });
      /*jshint camelcase: false */
      if (vm.service.auth_url || vm.service.name) {
        if (confirm('Clean all fields?')) {
          vm.service.auth_url = '';
          vm.service.name = '';
        }
      }
    }

    $rootScope.$on('currentCustomerUpdated', activate);

    function save() {
      vm.service.$save(success, error);

      function success() {
        projectsService.filterByCustomer = false;
        projectsService.getList().then(function(response) {
          for (var i = 0; response.length > i; i++) {
            projectCloudMembershipsService.addRow(response[i].url, vm.service.url);
          }
        });
        $state.go('services.list');
      }

      function error(response) {
        vm.errors = response.data;
      }
    }

    function cancel() {
      $state.go('services.list');
    }

    activate();

  }

})();

(function() {
  angular.module('ncsaas')
    .controller('ServiceDetailUpdateController',
      ['baseControllerClass', 'servicesService', '$stateParams', '$state', ServiceDetailUpdateController]);

  function ServiceDetailUpdateController(baseControllerClass, servicesService, $stateParams, $state) {
    var controllerScope = this;
    var Controller = baseControllerClass.extend({
      service: null,

      init:function() {
        this._super();
        this.activate();
      },
      activate:function() {
        var vm = this;
        servicesService.$get($stateParams.uuid).then(function(response) {
          vm.service = response;
        });
      },
      remove:function() {
        if (confirm('Are you sure you want to delete service?')) {
          this.service.$delete(
            function() {
              $state.go('services.list');
            },
            function(errors) {
              alert(errors.data.detail);
            }
          );
        }
      }
    });

    controllerScope.__proto__ = new Controller();
  }
})();
<|endoftext|>


<commit_before>angular
    .module('ngSharepoint.Lists')
    .factory('$query', $query);

function $query($spList) {
    var Query = function() {
        this.list = undefined;
        this.__columns = [];
        this.__type = undefined;
        this.__query = undefined;
        this.__limit = undefined;
        this.__serializer = undefined;
        this.__order = [];
        this.__data = {};
        this.read = function(cols) {
            if (angular.isUndefined(this.__type)) {
                this.__columns = cols;
                this.__type = 'read';
            }else {
                throw 'Cannot use read after another query type was selected';
            }
            return this;
        };
        this.create = function(data) {
            if (angular.isUndefined(this.__type)) {
                this.__type = 'create';
                if (angular.isDefined(data)) {
                    this.__data = data;
                }
            }else {
                throw 'Cannot use create after another query type was selected';
            }
            return this;
        };
        this.from = function(list) {
            this.list = list;
            return this;
        };
        this.in = function(list) {
            this.list = list;
            return this;
        };
        this.list = function(list) {
            this.list = list;
            return this;
        };
        this.update = function(data) {
            if (angular.isUndefined(this.__type)) {
                this.__type = 'update';
                if (angular.isDefined(data)) {
                    this.__data = data;
                }
            }else {
                throw 'Cannot use update after another query type was selected';
            }
            return this;
        };
        this.delete = function() {
            if (angular.isUndefined(this.__type)) {
                this.__type = 'delete';
            }else {
                throw 'Cannot use delete after another query type was selected';
            }
            return this;
        };
        this.where = function(col) {
            var Where = function(col, instance) {
                this.equals = function(value) {
                    instance.__query = {
                        comparator: 'equals',
                        column: col,
                        value: value
                    };
                    return instance;
                };
                this.greater = function(value) {
                    instance.__query = {
                        comparator: 'greater',
                        column: col,
                        value: value
                    };
                    return instance;
                };
                this.smaller = function(value) {
                    instance.__query = {
                        comparator: 'smaller',
                        column: col,
                        value: value
                    };
                    return instance;
                };
            };
            return new Where(col, this);
        };
        this.set = function(column, value) {
            this.__data[column] = value;
            return this;
        };
        this.value = function(column, value) {
            this.__data[column] = value;
            return this;
        };
        this.class = function(serializer) {
            this.__serializer = serializer;
            return this;
        };
        this.orderBy = function(field, asc) {
            if (angular.isUndefined(asc)) {
                asc = true;
            }
            this.__order.push({column: field, asc: asc});
            return this;
        };
        this.limit = function(limit) {
            this.__limit = limit;
            return this;
        };
        this.exec = function() {
            if (angular.isDefined(this.list) && angular.isString(this.list)) {
                var query = {};
                if (angular.isDefined(this.__type)) {
                    query.type = this.__type;
                }else {
                    throw 'No Query Type specified';
                }
                if (angular.isDefined(this.__columns)) {
                    query.columns = this.__columns;
                }
                if (angular.isDefined(this.__query)) {
                    query.query = this.__query;
                }
                if (angular.isDefined(this.__limit)) {
                    query.limit = this.__limit;
                }
                if (angular.isDefined(this.__serializer)) {
                    query.serializer = this.__serializer;
                }
                if (angular.isDefined(this.__order) &&
                    angular.isArray(this.__order) &&
                    this.__order.length > 0) {
                    query.order = this.__order;
                }
                if (angular.isDefined(this.__data) &&
                    angular.isObject(this.__data) &&
                    Object.getOwnPropertyNames(this.__data).length > 0) {
                    query.data = this.__data;
                }
                return $spList.getList(this.list).query(query);
            }else {
                throw 'No List specified';
            }
        };
        this.then = function(resolve, reject) {
            return this.exec().then(resolve, reject);
        };
    };
    return ({ //TODO: Reimplement this nested return mess
        'create': function(data) {
            return new Query().create(data);
        },
        'read': function(cols) {
            return new Query().read(cols);
        },
        'update': function(data) {
            return new Query().update(data);
        },
        'delete': function() {
            return new Query().delete();
        }
    });
}
<commit_msg>Added columns checks<commit_after>angular
    .module('ngSharepoint.Lists')
    .factory('$query', $query);

function $query($spList) {
    var Query = function() {
        this.list = undefined;
        this.__columns = [];
        this.__type = undefined;
        this.__query = undefined;
        this.__limit = undefined;
        this.__serializer = undefined;
        this.__order = [];
        this.__data = {};
        this.read = function(cols) {
            if (angular.isUndefined(this.__type)) {
                this.__columns = cols;
                this.__type = 'read';
            }else {
                throw 'Cannot use read after another query type was selected';
            }
            return this;
        };
        this.create = function(data) {
            if (angular.isUndefined(this.__type)) {
                this.__type = 'create';
                if (angular.isDefined(data)) {
                    this.__data = data;
                }
            }else {
                throw 'Cannot use create after another query type was selected';
            }
            return this;
        };
        this.from = function(list) {
            this.list = list;
            return this;
        };
        this.in = function(list) {
            this.list = list;
            return this;
        };
        this.list = function(list) {
            this.list = list;
            return this;
        };
        this.update = function(data) {
            if (angular.isUndefined(this.__type)) {
                this.__type = 'update';
                if (angular.isDefined(data)) {
                    this.__data = data;
                }
            }else {
                throw 'Cannot use update after another query type was selected';
            }
            return this;
        };
        this.delete = function() {
            if (angular.isUndefined(this.__type)) {
                this.__type = 'delete';
            }else {
                throw 'Cannot use delete after another query type was selected';
            }
            return this;
        };
        this.where = function(col) {
            var Where = function(col, instance) {
                this.equals = function(value) {
                    instance.__query = {
                        comparator: 'equals',
                        column: col,
                        value: value
                    };
                    return instance;
                };
                this.greater = function(value) {
                    instance.__query = {
                        comparator: 'greater',
                        column: col,
                        value: value
                    };
                    return instance;
                };
                this.smaller = function(value) {
                    instance.__query = {
                        comparator: 'smaller',
                        column: col,
                        value: value
                    };
                    return instance;
                };
            };
            return new Where(col, this);
        };
        this.set = function(column, value) {
            this.__data[column] = value;
            return this;
        };
        this.value = function(column, value) {
            this.__data[column] = value;
            return this;
        };
        this.class = function(serializer) {
            this.__serializer = serializer;
            return this;
        };
        this.orderBy = function(field, asc) {
            if (angular.isUndefined(asc)) {
                asc = true;
            }
            this.__order.push({column: field, asc: asc});
            return this;
        };
        this.limit = function(limit) {
            this.__limit = limit;
            return this;
        };
        this.exec = function() {
            if (angular.isDefined(this.list) && angular.isString(this.list)) {
                var query = {};
                if (angular.isDefined(this.__type)) {
                    query.type = this.__type;
                }else {
                    throw 'No Query Type specified';
                }
                if (angular.isDefined(this.__columns) &&
                    angular.isArray(this.__columns) &&
                    this.__columns.length > 0) {
                    query.columns = this.__columns;
                }
                if (angular.isDefined(this.__query)) {
                    query.query = this.__query;
                }
                if (angular.isDefined(this.__limit)) {
                    query.limit = this.__limit;
                }
                if (angular.isDefined(this.__serializer)) {
                    query.serializer = this.__serializer;
                }
                if (angular.isDefined(this.__order) &&
                    angular.isArray(this.__order) &&
                    this.__order.length > 0) {
                    query.order = this.__order;
                }
                if (angular.isDefined(this.__data) &&
                    angular.isObject(this.__data) &&
                    Object.getOwnPropertyNames(this.__data).length > 0) {
                    query.data = this.__data;
                }
                return $spList.getList(this.list).query(query);
            }else {
                throw 'No List specified';
            }
        };
        this.then = function(resolve, reject) {
            return this.exec().then(resolve, reject);
        };
    };
    return ({ //TODO: Reimplement this nested return mess
        'create': function(data) {
            return new Query().create(data);
        },
        'read': function(cols) {
            return new Query().read(cols);
        },
        'update': function(data) {
            return new Query().update(data);
        },
        'delete': function() {
            return new Query().delete();
        }
    });
}
<|endoftext|>


<commit_before>/*jslint vars: false, browser: true, nomen: true */
/*global MOOC: true, Backbone, $, _, gettext */

// Copyright 2012 Rooter Analysis S.L.
//
// 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.

if (_.isUndefined(window.MOOC)) {
    window.MOOC = {};
}

MOOC.ajax = {};

MOOC.ajax.showLoading = function () {
    "use strict";
    $(".loading").removeClass("hide");
};

MOOC.ajax.hideLoading = function () {
    "use strict";
    $(".loading").addClass("hide");
};

MOOC.ajax.host = "/api/v1/";

MOOC.ajax.getAbsoluteUrl = function (path) {
    "use strict";
    return MOOC.ajax.host + path;
};

MOOC.ajax.genericError = function (jqXHR, textStatus, errorThrown) {
    "use strict";
    var message;
    if (!_.isNull(textStatus)) {
        message = gettext("Error") + ": " + textStatus;
    } else {
        message = gettext("Unknown error with ajax petition");
    }
    if (!_.isNull(errorThrown)) {
        message += " - " + errorThrown;
    }
    MOOC.alerts.show(MOOC.alerts.ERROR, "AJAX " + gettext("error"), message);
};

MOOC.ajax.getResource = function (uri, callback) {
    "use strict";
    $.ajax(uri + "?format=json", {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getKQsByUnit = function (unit, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "kq/?format=json&unit=" + unit, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getAttachmentsByKQ = function (kq, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "attachment/?format=json&kq=" + kq, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getOptionsByQuestion = function (question, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "option/?format=json&question=" + question, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getAnswerByQuestion = function (question, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "answer/?format=json&question=" + question, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.sendAnswer = function (answer, callback) {
    "use strict";
    var url = MOOC.ajax.host + "answer/",
        method = "post",
        data = answer.toJSON();
    if (!answer.isNew()) {
        url += answer.get('question_id') + "/";
        method = "put";
    }
    $.ajax(url, {
        type: method,
        data: JSON.stringify(data),
        contentType: "application/json",
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.sendPRSubmission = function (submission, callback) {
    "use strict";
    var url = MOOC.ajax.host + "peer_review_submissions/";
    $.ajax(url, {
        type: "POST",
        data: JSON.stringify(submission),
        contentType: "application/json",
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getPRSubmission = function (kq, callback) {
    "use strict";
    var url = MOOC.ajax.host + "peer_review_submissions/?kq=" + kq;
    $.ajax(url, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.alerts = {};

MOOC.alerts.ERROR = "error";
MOOC.alerts.SUCCESS = "success";
MOOC.alerts.INFO = "info";

MOOC.alerts.show = function (type, title, message) {
    "use strict";
    var alert = $(".alert.alert-" + type);
    alert.find("h4").text(title);
    alert.find("p").text(message);
    alert.removeClass("hide");
    $("body").animate({ scrollTop: alert.offset().top }, 500);
    _.delay(function () {
        MOOC.alerts.hide();
    }, 10000);
};

MOOC.alerts.hide = function () {
    "use strict";
    $(".alert").addClass("hide");
};
<commit_msg>Bugfix asking for the questions' answers<commit_after>/*jslint vars: false, browser: true, nomen: true */
/*global MOOC: true, Backbone, $, _, gettext */

// Copyright 2012 Rooter Analysis S.L.
//
// 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.

if (_.isUndefined(window.MOOC)) {
    window.MOOC = {};
}

MOOC.ajax = {};

MOOC.ajax.showLoading = function () {
    "use strict";
    $(".loading").removeClass("hide");
};

MOOC.ajax.hideLoading = function () {
    "use strict";
    $(".loading").addClass("hide");
};

MOOC.ajax.host = "/api/v1/";

MOOC.ajax.getAbsoluteUrl = function (path) {
    "use strict";
    return MOOC.ajax.host + path;
};

MOOC.ajax.genericError = function (jqXHR, textStatus, errorThrown) {
    "use strict";
    var message;
    if (!_.isNull(textStatus)) {
        message = gettext("Error") + ": " + textStatus;
    } else {
        message = gettext("Unknown error with ajax petition");
    }
    if (!_.isNull(errorThrown)) {
        message += " - " + errorThrown;
    }
    MOOC.alerts.show(MOOC.alerts.ERROR, "AJAX " + gettext("error"), message);
};

MOOC.ajax.getResource = function (uri, callback) {
    "use strict";
    $.ajax(uri + "?format=json", {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getKQsByUnit = function (unit, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "kq/?format=json&unit=" + unit, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getAttachmentsByKQ = function (kq, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "attachment/?format=json&kq=" + kq, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getOptionsByQuestion = function (question, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "option/?format=json&question=" + question, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getAnswerByQuestion = function (question, callback) {
    "use strict";
    $.ajax(MOOC.ajax.host + "answer/?format=json&question_id=" + question, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.sendAnswer = function (answer, callback) {
    "use strict";
    var url = MOOC.ajax.host + "answer/",
        method = "post",
        data = answer.toJSON();
    if (!answer.isNew()) {
        url += answer.get('question_id') + "/";
        method = "put";
    }
    $.ajax(url, {
        type: method,
        data: JSON.stringify(data),
        contentType: "application/json",
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.sendPRSubmission = function (submission, callback) {
    "use strict";
    var url = MOOC.ajax.host + "peer_review_submissions/";
    $.ajax(url, {
        type: "POST",
        data: JSON.stringify(submission),
        contentType: "application/json",
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.ajax.getPRSubmission = function (kq, callback) {
    "use strict";
    var url = MOOC.ajax.host + "peer_review_submissions/?kq=" + kq;
    $.ajax(url, {
        success: callback,
        error: MOOC.ajax.genericError
    });
};

MOOC.alerts = {};

MOOC.alerts.ERROR = "error";
MOOC.alerts.SUCCESS = "success";
MOOC.alerts.INFO = "info";

MOOC.alerts.show = function (type, title, message) {
    "use strict";
    var alert = $(".alert.alert-" + type);
    alert.find("h4").text(title);
    alert.find("p").text(message);
    alert.removeClass("hide");
    $("body").animate({ scrollTop: alert.offset().top }, 500);
    _.delay(function () {
        MOOC.alerts.hide();
    }, 10000);
};

MOOC.alerts.hide = function () {
    "use strict";
    $(".alert").addClass("hide");
};
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react'
import { bool, object } from 'prop-types'
import { connect } from 'react-redux'

import { saveEndpoint } from '../../../store/actions'

import Modal from '../../../components/Modal/Modal'
import Button from '../../../components/Button/Button'
import Uploader from './Uploader'

const propTypes = {
  json: object.isRequired,
  show: bool.isRequired
}

const defaultProps = {
  json: {},
  show: false
}

class UploadingModal extends PureComponent {
  constructor (props) {
    super(props)

    this.state = {
      show: false,
      updatedJSON: null,
      json: null
    }
  }

  handleDragAndDrop = () => {}

  handleOpen = () => this.setState({ show: true })

  handleClose = () => this.setState({ show: false, json: null })

  setJSON = json => this.setState({
    updatedJSON: JSON.parse(json),
    json: JSON.parse(json),
  })

  getContent = file => e => this.setJSON(e.target.result)

  uploadFile = event => {
    const file = event.target.files[0]
    let reader = new FileReader()

    reader.onload = this.getContent(file)
    reader.readAsText(file)
  }

  handleUploadFile = () => {
    let input = document.createElement('input')

    input.type = 'file'
    input.id = 'import-json'
    input.onchange = this.uploadFile
    document.body.appendChild(input)
    input.click()
    document.body.removeChild(input)
  }

  handleUpdateJson = updatedJSON => this.setState({ updatedJSON })

  render () {
    return (

        <Button
          mod='primary'
          onClick={this.handleOpen}
        >
          Import JSON
        </Button>
        <Modal
          show={this.state.show}
          closeModal={this.handleClose}
          title={'Import from JSON'}
          message={
            <Uploader
              showTooltip={this.state.json}
              getContent={this.getContent}
              uploadFile={this.handleUploadFile}
              json={this.state.json}
              handleJSONonChange={this.handleUpdateJson}
            />
          }
          buttons={[
            <Button
              key='cancel'
              mod='default'
              onClick={this.handleClose}
            >
              Close
            </Button>,
            <Button
              key='upload'
              mod='primary'
              onClick={() => this.props.saveEndpoint(JSON.parse(this.state.updatedJSON))}
            >
              Upload
            </Button>
          ]}
        />

    )
  }
}

UploadingModal.propTypes = propTypes
UploadingModal.defaultProps = defaultProps

export default connect(
  null,
  {
    saveEndpoint
  }
)(UploadingModal)
<commit_msg>Save uploaded json<commit_after>import React, { PureComponent } from 'react'
import { bool, object } from 'prop-types'
import { connect } from 'react-redux'

import { saveEndpoint } from '../../../store/actions'

import Modal from '../../../components/Modal/Modal'
import Button from '../../../components/Button/Button'
import Uploader from './Uploader'

const propTypes = {
  json: object.isRequired,
  show: bool.isRequired
}

const defaultProps = {
  json: {},
  show: false
}

class UploadingModal extends PureComponent {
  constructor (props) {
    super(props)

    this.state = {
      show: false,
      updatedJSON: null,
      json: null
    }
  }

  handleDragAndDrop = () => {}

  handleOpen = () => this.setState({ show: true })

  handleClose = () => this.setState({ show: false, json: null })

  setJSON = json => this.setState({
    updatedJSON: JSON.parse(json),
    json: JSON.parse(json)
  })

  getContent = file => e => this.setJSON(e.target.result)

  uploadFile = event => {
    const file = event.target.files[0]
    let reader = new FileReader()

    reader.onload = this.getContent(file)
    reader.readAsText(file)
  }

  handleUploadFile = () => {
    let input = document.createElement('input')

    input.type = 'file'
    input.id = 'import-json'
    input.onchange = this.uploadFile
    document.body.appendChild(input)
    input.click()
    document.body.removeChild(input)
  }

  handleUpdateJson = updatedJSON => this.setState({ updatedJSON })

  render () {
    return (

        <Button
          mod='primary'
          onClick={this.handleOpen}
        >
          Import JSON
        </Button>
        <Modal
          show={this.state.show}
          closeModal={this.handleClose}
          title={'Import from JSON'}
          message={
            <Uploader
              showTooltip={this.state.json}
              getContent={this.getContent}
              uploadFile={this.handleUploadFile}
              json={this.state.json}
              handleJSONonChange={this.handleUpdateJson}
            />
          }
          buttons={[
            <Button
              key='cancel'
              mod='default'
              onClick={this.handleClose}
            >
              Close
            </Button>,
            <Button
              key='upload'
              mod='primary'
              onClick={() => this.props.saveEndpoint(JSON.parse(this.state.updatedJSON))}
            >
              Upload
            </Button>
          ]}
        />

    )
  }
}

UploadingModal.propTypes = propTypes
UploadingModal.defaultProps = defaultProps

export default connect(
  null,
  {
    saveEndpoint
  }
)(UploadingModal)
<|endoftext|>


<commit_before>'use strict';

const Ana = require('./ana_log');
const hyd = require('hydrolysis');
const path = require('path');

/**
 * @param {Object} obj - The object to strip properties from.
 * @param {Array.<string>} properties - An array of property names to remove.
 */
function removeProperties(obj, properties) {
  if (!properties || !obj) return;
  if (typeof obj === 'object') {
    for (var prop of properties) {
      delete obj[prop];
    }
    Object.keys(obj).forEach(x => removeProperties(obj[x], properties));
  } else if (Array.isArray(obj)) {
    obj.forEach(val => removeProperties(val, properties));
  }
}

/**
 * Service for running Hydrolysis on the local machine.
 */
class Hydrolysis {
  /**
   * Runs Hydrolysis against each main html file in the given list.
   * Merges Element and Behavior key/values from each main html into one set each.
   * Output looks like {elementsByTagName:{}, behaviorsByName:{}}.
   * @param {Array.<string>} mainHtmlPaths - paths to mainHtml files
   * @return {Promise.<Array.<Object>>} a promise, returning the element and behavior data.
   */
  analyze(mainHtmlPaths) {
    /*
     * Run Hydrolysis on given paths and extract relevant data. Failure is fine, we just ignore it.
     */
    return new Promise(resolve => {
      Ana.log("hydrolysis/analyze", mainHtmlPaths);
      var data = {
        elementsByTagName: {},
        behaviorsByName: {}
      };

      Promise.all(
        mainHtmlPaths.map(mainHtmlPath => {
          return hyd.Analyzer.analyze(mainHtmlPath, {clean: true, filter: () => false})
            .then(analyzer => {

              // There's a weird name.indexOf === 0 thing in hydrolysis that means that
              // paper-dialog-x will be included in paper-dialog. We don't want that, so
              // we need to add this additional filtering.
              var dirName = path.dirname(mainHtmlPath);
              var pathFilter = item => !path.relative(dirName, item.contentHref).includes("..");

              // Get only the elements in the folder containing the element we're looking at.
              var elements = analyzer.elementsForFolder(mainHtmlPath);
              elements = elements.filter(pathFilter);
              var behaviors = analyzer.behaviorsForFolder(mainHtmlPath);
              behaviors = behaviors.filter(pathFilter);

              Ana.debug("Got elements and behaviors");

              // Strip ridiculously huge (or circular) fields from elements.
              removeProperties(elements, ["scriptElement", "javascriptNode", "observerNode"]);
              removeProperties(behaviors, ["scriptElement", "javascriptNode", "observerNode"]);

              Ana.debug("Filtered elements");

              // Get the element names that were in the folder.
              var els = elements.map(el => el.is);
              var bes = behaviors.map(be => be.is);
              Ana.debug("Elements", els);
              Ana.debug("Behaviors", bes);

              // Copy the elements from the folder to our output data.
              els.forEach(el => data.elementsByTagName[el] = elements[els.indexOf(el)]);
              bes.forEach(be => data.behaviorsByName[be] = behaviors[bes.indexOf(be)]);

            }).catch(function() {
              Ana.fail("hydrolysis/analyze", mainHtmlPath);
            });
        })
      ).then(function() {
        Ana.success("hydrolysis/analyze", mainHtmlPaths);
        resolve(data);
      });
    });
  }
}

module.exports = Hydrolysis;
<commit_msg>Filter URI dependencies from hydrolysis (#743)<commit_after>'use strict';

const Ana = require('./ana_log');
const hyd = require('hydrolysis');
const path = require('path');

/**
 * @param {Object} obj - The object to strip properties from.
 * @param {Array.<string>} properties - An array of property names to remove.
 */
function removeProperties(obj, properties) {
  if (!properties || !obj) return;
  if (typeof obj === 'object') {
    for (var prop of properties) {
      delete obj[prop];
    }
    Object.keys(obj).forEach(x => removeProperties(obj[x], properties));
  } else if (Array.isArray(obj)) {
    obj.forEach(val => removeProperties(val, properties));
  }
}

/**
 * Service for running Hydrolysis on the local machine.
 */
class Hydrolysis {
  /**
   * Runs Hydrolysis against each main html file in the given list.
   * Merges Element and Behavior key/values from each main html into one set each.
   * Output looks like {elementsByTagName:{}, behaviorsByName:{}}.
   * @param {Array.<string>} mainHtmlPaths - paths to mainHtml files
   * @return {Promise.<Array.<Object>>} a promise, returning the element and behavior data.
   */
  analyze(mainHtmlPaths) {
    /*
     * Run Hydrolysis on given paths and extract relevant data. Failure is fine, we just ignore it.
     */
    return new Promise(resolve => {
      Ana.log("hydrolysis/analyze", mainHtmlPaths);
      var data = {
        elementsByTagName: {},
        behaviorsByName: {}
      };

      Promise.all(
        mainHtmlPaths.map(mainHtmlPath => {
          return hyd.Analyzer.analyze(mainHtmlPath,
            {
              clean: true,
              filter: (path) => {
                // Only filter out URIs (we want to look at any and all files in relative dirs)
                return path.indexOf('http') == 0 || path.indexOf('//') == 0;
              }
            })
            .then(analyzer => {

              // There's a weird name.indexOf === 0 thing in hydrolysis that means that
              // paper-dialog-x will be included in paper-dialog. We don't want that, so
              // we need to add this additional filtering.
              var dirName = path.dirname(mainHtmlPath);
              var pathFilter = item => !path.relative(dirName, item.contentHref).includes("..");

              // Get only the elements in the folder containing the element we're looking at.
              var elements = analyzer.elementsForFolder(mainHtmlPath);
              elements = elements.filter(pathFilter);
              var behaviors = analyzer.behaviorsForFolder(mainHtmlPath);
              behaviors = behaviors.filter(pathFilter);

              Ana.debug("Got elements and behaviors");

              // Strip ridiculously huge (or circular) fields from elements.
              removeProperties(elements, ["scriptElement", "javascriptNode", "observerNode"]);
              removeProperties(behaviors, ["scriptElement", "javascriptNode", "observerNode"]);

              Ana.debug("Filtered elements");

              // Get the element names that were in the folder.
              var els = elements.map(el => el.is);
              var bes = behaviors.map(be => be.is);
              Ana.debug("Elements", els);
              Ana.debug("Behaviors", bes);

              // Copy the elements from the folder to our output data.
              els.forEach(el => data.elementsByTagName[el] = elements[els.indexOf(el)]);
              bes.forEach(be => data.behaviorsByName[be] = behaviors[bes.indexOf(be)]);

            }).catch(function() {
              Ana.fail("hydrolysis/analyze", mainHtmlPath);
            });
        })
      ).then(function() {
        Ana.success("hydrolysis/analyze", mainHtmlPaths);
        resolve(data);
      });
    });
  }
}

module.exports = Hydrolysis;
<|endoftext|>