<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');
var filters = require('views/common/filter_view');

App.TableView = Em.View.extend(App.UserPref, {

  init: function() {
    this.set('filterConditions', []);
    this._super();
  },

  /**
   * Defines to show pagination or show all records
   * @type {Boolean}
   */
  pagination: true,

  /**
   * Shows if all data is loaded and filtered
   * @type {Boolean}
   */
  filteringComplete: false,

  /**
   * intermediary for filteringComplete
   * @type {Boolean}
   */
  tableFilteringComplete: false,

  /**
   * The number of rows to show on every page
   * The value should be a number converted into string type in order to support select element API
   * Example: "10", "25"
   * @type {String}
   */
  displayLength: null,

  /**
   * default value of display length
   * The value should be a number converted into string type in order to support select element API
   * Example: "10", "25"
   */
  defaultDisplayLength: "10",

  /**
   * number of items in table after applying filters
   */
  filteredCount: Em.computed.alias('filteredContent.length'),

  /**
   * total number of items in table before applying filters
   */
  totalCount: Em.computed.alias('content.length'),

  /**
   * Do filtering, using saved in the local storage filter conditions
   */
  willInsertElement: function () {
    var self = this;
    var name = this.get('controller.name');
    if (!this.get('displayLength') && this.get('state') !== "inBuffer") {
      if (App.db.getDisplayLength(name)) {
        self.set('displayLength', App.db.getDisplayLength(name));
        Em.run.next(function () {
          self.initFilters();
        });
      } else {
        if (!$.mocho) {
          this.getUserPref(this.displayLengthKey()).complete(function () {
            self.initFilters();
          });
        }
      }
    }
  },

  /**
   * initialize filters
   * restore values from local DB
   * or clear filters in case there is no filters to restore
   */
  initFilters: function () {
    var name = this.get('controller.name');
    var self = this;
    var filterConditions = App.db.getFilterConditions(name);
    if (!Em.isEmpty(filterConditions)) {
      this.set('filterConditions', filterConditions);

      var childViews = this.get('childViews');

      filterConditions.forEach(function (condition, index, filteredConditions) {
        var view = !Em.isNone(condition.iColumn) && childViews.findProperty('column', condition.iColumn);
        if (view) {
          if (view.get('emptyValue')) {
            view.clearFilter();
            self.saveFilterConditions(condition.iColumn, view.get('appliedEmptyValue'), condition.type, false);
          } else {
            view.setValue(condition.value);
          }
          Em.run.next(function () {
            view.showClearFilter();
            // check if it is the last iteration
            if (filteredConditions.length - index - 1 === 0) {
              self.set('tableFilteringComplete', true);
            }
          });
        }
      });
    } else {
      this.set('tableFilteringComplete', true);
    }
  },

  /**
   * Persist-key of current table displayLength property
   * @param {String} loginName current user login name
   * @returns {String}
   */
  displayLengthKey: function (loginName) {
    if (App.get('testMode')) {
      return 'pagination_displayLength';
    }
    loginName = loginName ? loginName : App.router.get('loginName');
    return this.get('controller.name') + '-pagination-displayLength-' + loginName;
  },

  /**
   * Set received from server value to displayLengthOnLoad
   * @param {Number} response
   * @param {Object} request
   * @param {Object} data
   * @returns {*}
   */
  getUserPrefSuccessCallback: function (response, request, data) {
    this.set('displayLength', response);
    return response;
  },

  /**
   * Set default value to displayLength (and send it on server) if value wasn't found on server
   * @returns {Number}
   */
  getUserPrefErrorCallback: function () {
    // this user is first time login
    var displayLengthDefault = this.get('defaultDisplayLength');
    this.set('displayLength', displayLengthDefault);
    if (App.isAuthorized('SERVICE.VIEW_METRICS')) {
      this.saveDisplayLength();
    }
    this.filter();
    return displayLengthDefault;
  },

  /**
   * Return pagination information displayed on the page
   * @type {String}
   */
  paginationInfo: Em.computed.i18nFormat('tableView.filters.paginationInfo', 'startIndex', 'endIndex', 'filteredCount'),

  paginationLeft: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if (this.get("parentView.startIndex") > 1) {
        return "paginate_previous";
      }
      return "paginate_disabled_previous";
    }.property("parentView.startIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_previous") {
        this.get('parentView').previousPage();
      }
    }
  }),

  paginationRight: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if ((this.get("parentView.endIndex")) < this.get("parentView.filteredCount")) {
        return "paginate_next";
      }
      return "paginate_disabled_next";
    }.property("parentView.endIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_next") {
        this.get('parentView').nextPage();
      }
    }
  }),

  paginationFirst: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if ((this.get("parentView.endIndex")) > parseInt(this.get("parentView.displayLength"))) {
        return "paginate_previous";
      }
      return "paginate_disabled_previous";
    }.property("parentView.endIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_previous") {
        this.get('parentView').firstPage();
      }
    }
  }),

  paginationLast: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if (this.get("parentView.endIndex") !== this.get("parentView.filteredCount")) {
        return "paginate_next";
      }
      return "paginate_disabled_next";
    }.property("parentView.endIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_next") {
        this.get('parentView').lastPage();
      }
    }
  }),

  /**
   * Select View with list of "rows-per-page" options
   * @type {Ember.View}
   */
  rowsPerPageSelectView: Em.Select.extend({
    content: ['10', '25', '50', '100'],
    change: function () {
      this.get('parentView').saveDisplayLength();
    }
  }),

  /**
   * Start index for displayed content on the page
   */
  startIndex: 1,

  /**
   * Calculate end index for displayed content on the page
   */
  endIndex: function () {
    if (this.get('pagination') && this.get('displayLength')) {
      return Math.min(this.get('filteredCount'), this.get('startIndex') + parseInt(this.get('displayLength')) - 1);
    } else {
      return this.get('filteredCount') || 0;
    }
  }.property('startIndex', 'displayLength', 'filteredCount'),

  /**
   * Onclick handler for previous page button on the page
   */
  previousPage: function () {
    var result = this.get('startIndex') - parseInt(this.get('displayLength'));
    this.set('startIndex', (result < 2) ? 1 : result);
  },

  /**
   * Onclick handler for next page button on the page
   */
  nextPage: function () {
    var result = this.get('startIndex') + parseInt(this.get('displayLength'));
    if (result - 1 < this.get('filteredCount')) {
      this.set('startIndex', result);
    }
  },
  /**
   * Onclick handler for first page button on the page
   */
  firstPage: function () {
    this.set('startIndex', 1);
  },
  /**
   * Onclick handler for last page button on the page
   */
  lastPage: function () {
    var pagesCount = this.get('filteredCount') / parseInt(this.get('displayLength'));
    var startIndex = (this.get('filteredCount') % parseInt(this.get('displayLength')) === 0) ?
      (pagesCount - 1) * parseInt(this.get('displayLength')) :
      Math.floor(pagesCount) * parseInt(this.get('displayLength'));
    this.set('startIndex', ++startIndex);
  },

  /**
   * Calculates default value for startIndex property after applying filter or changing displayLength
   */
  updatePaging: function (controller, property) {
    var displayLength = this.get('displayLength');
    var filteredContentLength = this.get('filteredCount');
    if (property == 'displayLength') {
      this.set('startIndex', Math.min(1, filteredContentLength));
    } else if (!filteredContentLength) {
      this.set('startIndex', 0);
    } else if (this.get('startIndex') > filteredContentLength) {
      this.set('startIndex', Math.floor((filteredContentLength - 1) / displayLength) * displayLength + 1);
    } else if (!this.get('startIndex')) {
      this.set('startIndex', 1);
    }
  }.observes('displayLength', 'filteredCount'),

  /**
   * Apply each filter to each row
   *
   * @param {Number} iColumn number of column by which filter
   * @param {Object} value
   * @param {String} type
   */
  updateFilter: function (iColumn, value, type) {
    this.saveFilterConditions(iColumn, value, type, false);
    this.filtersUsedCalc();
    this.filter();
  },

  /**
   * save filter conditions to local storage
   * @param iColumn {Number}
   * @param value {String|Array}
   * @param type {String}
   * @param skipFilter {Boolean}
   */
  saveFilterConditions: function(iColumn, value, type, skipFilter) {
    var filterCondition = this.get('filterConditions').findProperty('iColumn', iColumn);

    if (filterCondition) {
      filterCondition.value = value;
      filterCondition.skipFilter = skipFilter;
    } else {
      filterCondition = {
        skipFilter: skipFilter,
        iColumn: iColumn,
        value: value,
        type: type
      };
      this.get('filterConditions').push(filterCondition);
    }

    this.saveAllFilterConditions();
  },

  /**
   * Save not empty filterConditions to the localStorage
   *
   * @method saveAllFilterConditions
   */
  saveAllFilterConditions: function () {
    var filterConditions = this.get('filterConditions');
    // remove empty entries
    filterConditions = filterConditions.filter(function(item) {
      return !Em.isEmpty(item.value);
    });
    this.set('filterConditions', filterConditions);
    App.db.setFilterConditions(this.get('controller.name'), filterConditions);
  },

  saveDisplayLength: function() {
    var self = this;
    Em.run.next(function() {
      App.db.setDisplayLength(self.get('controller.name'), self.get('displayLength'));
      if (!App.get('testMode')) {
        if (App.isAuthorized('SERVICE.VIEW_METRICS')) {
          self.postUserPref(self.displayLengthKey(), self.get('displayLength'));
        }
      }
    });
  },

  clearFilterConditionsFromLocalStorage: function() {
    var result = false;
    var currentFCs = App.db.getFilterConditions(this.get('controller.name'));
    if (currentFCs != null) {
      App.db.setFilterConditions(this.get('controller.name'), null);
      result = true;
    }
    return result;
  },

  /**
   * Contain filter conditions for each column
   * @type {Array}
   */
  filterConditions: [],

  /**
   * Contains content after implementing filters
   * @type {Array}
   */
  filteredContent: [],

  /**
   * Determine if filteredContent is empty or not
   * @type {Boolean}
   */
  hasFilteredItems: Em.computed.bool('filteredCount'),

  /**
   * Contains content to show on the current page of data page view
   * @type {Array}
   */
  pageContent: function () {
    return this.get('filteredContent').slice(this.get('startIndex') - 1, this.get('endIndex'));
  }.property('filteredCount', 'startIndex', 'endIndex'),

  /**
   * flag to toggle displaying filtered hosts counter
   */
  showFilteredContent: function () {
    var result = false;
    if (this.get('filterConditions.length') > 0) {
      this.get('filterConditions').forEach(function(f) {
        if (f.value) {
          if (Em.typeOf(f.value) == "array") {
            if (f.value[0] || f.value[1]) {
              result = true;
            }
          } else {
            result = true;
          }
        }
      });
    }
    return result;
  }.property('filteredContent.length'),
  /**
   * Filter table by filterConditions
   */
  filter: function () {
    var content = this.get('content');
    var filterConditions = this.get('filterConditions').filterProperty('value');
    var result;
    var assoc = this.get('colPropAssoc');
    if (filterConditions.length) {
      result = content.filter(function (item) {
        var match = true;
        filterConditions.forEach(function (condition) {
          var filterFunc = filters.getFilterByType(condition.type, false);
          if (match) {
            match = filterFunc(item.get(assoc[condition.iColumn]), condition.value);
          }
        });
        return match;
      });
      this.set('filteredContent', result);
    } else {
      this.set('filteredContent', content ? content.toArray() : []);
    }
  }.observes('content.length'),

  /**
   * Does any filter is used on the page
   * @type {Boolean}
   */
  filtersUsed: false,

  /**
   * Determine if some filters are used on the page
   * Set filtersUsed value
   */
  filtersUsedCalc: function() {
    var filterConditions = this.get('filterConditions');
    if (!filterConditions.length) {
      this.set('filtersUsed', false);
      return;
    }
    var filtersUsed = false;
    filterConditions.forEach(function(filterCondition) {
      if (filterCondition.value.toString() !== '') {
        filtersUsed = true;
      }
    });
    this.set('filtersUsed', filtersUsed);
  },

  /**
   * Run clearFilter in the each child filterView
   */
  clearFilters: function() {
    this.set('filterConditions', []);
    this.get('childViews').forEach(function(childView) {
      Em.tryInvoke(childView, 'clearFilter');
    });
  }

});
<commit_msg>AMBARI-14879 Alerts page pagination issue.(ababiichuk)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');
var filters = require('views/common/filter_view');

App.TableView = Em.View.extend(App.UserPref, {

  init: function() {
    this.set('filterConditions', []);
    this._super();
  },

  /**
   * Defines to show pagination or show all records
   * @type {Boolean}
   */
  pagination: true,

  /**
   * Shows if all data is loaded and filtered
   * @type {Boolean}
   */
  filteringComplete: false,

  /**
   * intermediary for filteringComplete
   * @type {Boolean}
   */
  tableFilteringComplete: false,

  /**
   * The number of rows to show on every page
   * The value should be a number converted into string type in order to support select element API
   * Example: "10", "25"
   * @type {String}
   */
  displayLength: null,

  /**
   * default value of display length
   * The value should be a number converted into string type in order to support select element API
   * Example: "10", "25"
   */
  defaultDisplayLength: "10",

  /**
   * number of items in table after applying filters
   */
  filteredCount: Em.computed.alias('filteredContent.length'),

  /**
   * total number of items in table before applying filters
   */
  totalCount: Em.computed.alias('content.length'),

  /**
   * Do filtering, using saved in the local storage filter conditions
   */
  willInsertElement: function () {
    var self = this;
    var name = this.get('controller.name');
    if (!this.get('displayLength')) {
      var displayLength = App.db.getDisplayLength(name);
      if (displayLength) {
        if (this.get('state') !== "inBuffer") {
          self.set('displayLength', displayLength);
          self.initFilters();
        } else {
          Em.run.next(function () {
            self.set('displayLength', displayLength);
            self.initFilters();
          });
        }
      } else {
        if (!$.mocho) {
          this.getUserPref(this.displayLengthKey()).complete(function () {
            self.initFilters();
          });
        }
      }
    }
  },

  /**
   * initialize filters
   * restore values from local DB
   * or clear filters in case there is no filters to restore
   */
  initFilters: function () {
    var name = this.get('controller.name');
    var self = this;
    var filterConditions = App.db.getFilterConditions(name);
    if (!Em.isEmpty(filterConditions)) {
      this.set('filterConditions', filterConditions);

      var childViews = this.get('childViews');

      filterConditions.forEach(function (condition, index, filteredConditions) {
        var view = !Em.isNone(condition.iColumn) && childViews.findProperty('column', condition.iColumn);
        if (view) {
          if (view.get('emptyValue')) {
            view.clearFilter();
            self.saveFilterConditions(condition.iColumn, view.get('appliedEmptyValue'), condition.type, false);
          } else {
            view.setValue(condition.value);
          }
          Em.run.next(function () {
            view.showClearFilter();
            // check if it is the last iteration
            if (filteredConditions.length - index - 1 === 0) {
              self.set('tableFilteringComplete', true);
            }
          });
        }
      });
    } else {
      this.set('tableFilteringComplete', true);
    }
  },

  /**
   * Persist-key of current table displayLength property
   * @param {String} loginName current user login name
   * @returns {String}
   */
  displayLengthKey: function (loginName) {
    if (App.get('testMode')) {
      return 'pagination_displayLength';
    }
    loginName = loginName ? loginName : App.router.get('loginName');
    return this.get('controller.name') + '-pagination-displayLength-' + loginName;
  },

  /**
   * Set received from server value to displayLengthOnLoad
   * @param {Number} response
   * @param {Object} request
   * @param {Object} data
   * @returns {*}
   */
  getUserPrefSuccessCallback: function (response, request, data) {
    this.set('displayLength', response);
    return response;
  },

  /**
   * Set default value to displayLength (and send it on server) if value wasn't found on server
   * @returns {Number}
   */
  getUserPrefErrorCallback: function () {
    // this user is first time login
    var displayLengthDefault = this.get('defaultDisplayLength');
    this.set('displayLength', displayLengthDefault);
    if (App.isAuthorized('SERVICE.VIEW_METRICS')) {
      this.saveDisplayLength();
    }
    this.filter();
    return displayLengthDefault;
  },

  /**
   * Return pagination information displayed on the page
   * @type {String}
   */
  paginationInfo: Em.computed.i18nFormat('tableView.filters.paginationInfo', 'startIndex', 'endIndex', 'filteredCount'),

  paginationLeft: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if (this.get("parentView.startIndex") > 1) {
        return "paginate_previous";
      }
      return "paginate_disabled_previous";
    }.property("parentView.startIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_previous") {
        this.get('parentView').previousPage();
      }
    }
  }),

  paginationRight: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if ((this.get("parentView.endIndex")) < this.get("parentView.filteredCount")) {
        return "paginate_next";
      }
      return "paginate_disabled_next";
    }.property("parentView.endIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_next") {
        this.get('parentView').nextPage();
      }
    }
  }),

  paginationFirst: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if ((this.get("parentView.endIndex")) > parseInt(this.get("parentView.displayLength"))) {
        return "paginate_previous";
      }
      return "paginate_disabled_previous";
    }.property("parentView.endIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_previous") {
        this.get('parentView').firstPage();
      }
    }
  }),

  paginationLast: Ember.View.extend({
    tagName: 'a',
    template: Ember.Handlebars.compile(''),
    classNameBindings: ['class'],
    class: function () {
      if (this.get("parentView.endIndex") !== this.get("parentView.filteredCount")) {
        return "paginate_next";
      }
      return "paginate_disabled_next";
    }.property("parentView.endIndex", 'parentView.filteredCount'),

    click: function () {
      if (this.get('class') === "paginate_next") {
        this.get('parentView').lastPage();
      }
    }
  }),

  /**
   * Select View with list of "rows-per-page" options
   * @type {Ember.View}
   */
  rowsPerPageSelectView: Em.Select.extend({
    content: ['10', '25', '50', '100'],
    change: function () {
      this.get('parentView').saveDisplayLength();
    }
  }),

  /**
   * Start index for displayed content on the page
   */
  startIndex: 1,

  /**
   * Calculate end index for displayed content on the page
   */
  endIndex: function () {
    if (this.get('pagination') && this.get('displayLength')) {
      return Math.min(this.get('filteredCount'), this.get('startIndex') + parseInt(this.get('displayLength')) - 1);
    } else {
      return this.get('filteredCount') || 0;
    }
  }.property('startIndex', 'displayLength', 'filteredCount'),

  /**
   * Onclick handler for previous page button on the page
   */
  previousPage: function () {
    var result = this.get('startIndex') - parseInt(this.get('displayLength'));
    this.set('startIndex', (result < 2) ? 1 : result);
  },

  /**
   * Onclick handler for next page button on the page
   */
  nextPage: function () {
    var result = this.get('startIndex') + parseInt(this.get('displayLength'));
    if (result - 1 < this.get('filteredCount')) {
      this.set('startIndex', result);
    }
  },
  /**
   * Onclick handler for first page button on the page
   */
  firstPage: function () {
    this.set('startIndex', 1);
  },
  /**
   * Onclick handler for last page button on the page
   */
  lastPage: function () {
    var pagesCount = this.get('filteredCount') / parseInt(this.get('displayLength'));
    var startIndex = (this.get('filteredCount') % parseInt(this.get('displayLength')) === 0) ?
      (pagesCount - 1) * parseInt(this.get('displayLength')) :
      Math.floor(pagesCount) * parseInt(this.get('displayLength'));
    this.set('startIndex', ++startIndex);
  },

  /**
   * Calculates default value for startIndex property after applying filter or changing displayLength
   */
  updatePaging: function (controller, property) {
    var displayLength = this.get('displayLength');
    var filteredContentLength = this.get('filteredCount');
    if (property == 'displayLength') {
      this.set('startIndex', Math.min(1, filteredContentLength));
    } else if (!filteredContentLength) {
      this.set('startIndex', 0);
    } else if (this.get('startIndex') > filteredContentLength) {
      this.set('startIndex', Math.floor((filteredContentLength - 1) / displayLength) * displayLength + 1);
    } else if (!this.get('startIndex')) {
      this.set('startIndex', 1);
    }
  }.observes('displayLength', 'filteredCount'),

  /**
   * Apply each filter to each row
   *
   * @param {Number} iColumn number of column by which filter
   * @param {Object} value
   * @param {String} type
   */
  updateFilter: function (iColumn, value, type) {
    this.saveFilterConditions(iColumn, value, type, false);
    this.filtersUsedCalc();
    this.filter();
  },

  /**
   * save filter conditions to local storage
   * @param iColumn {Number}
   * @param value {String|Array}
   * @param type {String}
   * @param skipFilter {Boolean}
   */
  saveFilterConditions: function(iColumn, value, type, skipFilter) {
    var filterCondition = this.get('filterConditions').findProperty('iColumn', iColumn);

    if (filterCondition) {
      filterCondition.value = value;
      filterCondition.skipFilter = skipFilter;
    } else {
      filterCondition = {
        skipFilter: skipFilter,
        iColumn: iColumn,
        value: value,
        type: type
      };
      this.get('filterConditions').push(filterCondition);
    }

    this.saveAllFilterConditions();
  },

  /**
   * Save not empty filterConditions to the localStorage
   *
   * @method saveAllFilterConditions
   */
  saveAllFilterConditions: function () {
    var filterConditions = this.get('filterConditions');
    // remove empty entries
    filterConditions = filterConditions.filter(function(item) {
      return !Em.isEmpty(item.value);
    });
    this.set('filterConditions', filterConditions);
    App.db.setFilterConditions(this.get('controller.name'), filterConditions);
  },

  saveDisplayLength: function() {
    var self = this;
    Em.run.next(function() {
      App.db.setDisplayLength(self.get('controller.name'), self.get('displayLength'));
      if (!App.get('testMode')) {
        if (App.isAuthorized('SERVICE.VIEW_METRICS')) {
          self.postUserPref(self.displayLengthKey(), self.get('displayLength'));
        }
      }
    });
  },

  clearFilterConditionsFromLocalStorage: function() {
    var result = false;
    var currentFCs = App.db.getFilterConditions(this.get('controller.name'));
    if (currentFCs != null) {
      App.db.setFilterConditions(this.get('controller.name'), null);
      result = true;
    }
    return result;
  },

  /**
   * Contain filter conditions for each column
   * @type {Array}
   */
  filterConditions: [],

  /**
   * Contains content after implementing filters
   * @type {Array}
   */
  filteredContent: [],

  /**
   * Determine if filteredContent is empty or not
   * @type {Boolean}
   */
  hasFilteredItems: Em.computed.bool('filteredCount'),

  /**
   * Contains content to show on the current page of data page view
   * @type {Array}
   */
  pageContent: function () {
    return this.get('filteredContent').slice(this.get('startIndex') - 1, this.get('endIndex'));
  }.property('filteredCount', 'startIndex', 'endIndex'),

  /**
   * flag to toggle displaying filtered hosts counter
   */
  showFilteredContent: function () {
    var result = false;
    if (this.get('filterConditions.length') > 0) {
      this.get('filterConditions').forEach(function(f) {
        if (f.value) {
          if (Em.typeOf(f.value) == "array") {
            if (f.value[0] || f.value[1]) {
              result = true;
            }
          } else {
            result = true;
          }
        }
      });
    }
    return result;
  }.property('filteredContent.length'),
  /**
   * Filter table by filterConditions
   */
  filter: function () {
    var content = this.get('content');
    var filterConditions = this.get('filterConditions').filterProperty('value');
    var result;
    var assoc = this.get('colPropAssoc');
    if (filterConditions.length) {
      result = content.filter(function (item) {
        var match = true;
        filterConditions.forEach(function (condition) {
          var filterFunc = filters.getFilterByType(condition.type, false);
          if (match) {
            match = filterFunc(item.get(assoc[condition.iColumn]), condition.value);
          }
        });
        return match;
      });
      this.set('filteredContent', result);
    } else {
      this.set('filteredContent', content ? content.toArray() : []);
    }
  }.observes('content.length'),

  /**
   * Does any filter is used on the page
   * @type {Boolean}
   */
  filtersUsed: false,

  /**
   * Determine if some filters are used on the page
   * Set filtersUsed value
   */
  filtersUsedCalc: function() {
    var filterConditions = this.get('filterConditions');
    if (!filterConditions.length) {
      this.set('filtersUsed', false);
      return;
    }
    var filtersUsed = false;
    filterConditions.forEach(function(filterCondition) {
      if (filterCondition.value.toString() !== '') {
        filtersUsed = true;
      }
    });
    this.set('filtersUsed', filtersUsed);
  },

  /**
   * Run clearFilter in the each child filterView
   */
  clearFilters: function() {
    this.set('filterConditions', []);
    this.get('childViews').forEach(function(childView) {
      Em.tryInvoke(childView, 'clearFilter');
    });
  }

});
<|endoftext|>


<commit_before>/**
 * CollaboratorController
 *
 * @description :: Server-side logic for managing collaborators
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

var _ = require('lodash');
var md5 = require('md5');

var self = module.exports = {

	findById: function(req, res) {
    var id = req.param('id');

    Collaborator.findOne({
      where: {
        id: id
      }
    }).then(function(collaboratorInstance) {
      if(collaboratorInstance === null) return res.notFound();
      else {
        return res.redirect(301, collaboratorInstance.uri);
      }
    }).catch(function(err) {
      return res.negotiate(err);
    });

  },

  findByName: function(req, res) {
    var name = req.param('name');

    Package.findAll({
      include: [
        { model: PackageVersion,
          as: 'latest_version',
          attributes:['id', 'package_name', 'version', 'title', 'release_date', 'license', 'url', 'maintainer_id'],
          include: [
            { model: Collaborator, as: 'maintainer' },
            { model: Collaborator, as: 'collaborators'},
          ]
        }
      ],
      where: {
        $or:[
          sequelize.literal("`latest_version.maintainer`.`name` = '" + name + "'"),
          sequelize.literal("`latest_version.collaborators`.`name` = '" + name + "'"),
        ]
      }
    }).then(function(packages) {
      if(packages === null) return res.notFound();
      else {
        var json = {name: name };

        json.packages = _.map(packages, function(package) {
          var latest = package.latest_version;
          if (latest.maintainer.name === name) {
            latest.is_maintainer = true;
          }
          var collaborators = _.filter(latest.collaborators, function(c) {
            return c.name === name;
          });

          if (collaborators.length > 0) {
            latest.is_contributor = true;
          }
          if(!json.email && latest.maintainer.email) {
            json.email = latest.maintainer.email;
          }
          if(!json.email && collaborators.length > 0 && collaborators[0].email) {
            json.email = collaborators[0].email;
          }
          return latest;
        });
        json.gravatar_url = 'https://www.gravatar.com/avatar/' + md5(_.trim(json.email).toLowerCase());
        json.packages = _.sortBy(json.packages, ['is_maintainer']);

        return res.ok(json, 'collaborator/show.ejs');
      }
    });

  }
};

<commit_msg>fix maintainer email<commit_after>/**
 * CollaboratorController
 *
 * @description :: Server-side logic for managing collaborators
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

var _ = require('lodash');
var md5 = require('md5');

var self = module.exports = {

	findById: function(req, res) {
    var id = req.param('id');

    Collaborator.findOne({
      where: {
        id: id
      }
    }).then(function(collaboratorInstance) {
      if(collaboratorInstance === null) return res.notFound();
      else {
        return res.redirect(301, collaboratorInstance.uri);
      }
    }).catch(function(err) {
      return res.negotiate(err);
    });

  },

  findByName: function(req, res) {
    var name = req.param('name');

    Package.findAll({
      include: [
        { model: PackageVersion,
          as: 'latest_version',
          attributes:['id', 'package_name', 'version', 'title', 'release_date', 'license', 'url', 'maintainer_id'],
          include: [
            { model: Collaborator, as: 'maintainer' },
            { model: Collaborator, as: 'collaborators'},
          ]
        }
      ],
      where: {
        $or:[
          sequelize.literal("`latest_version.maintainer`.`name` = '" + name + "'"),
          sequelize.literal("`latest_version.collaborators`.`name` = '" + name + "'"),
        ]
      }
    }).then(function(packages) {
      if(packages === null) return res.notFound();
      else {
        var json = {name: name };

        json.packages = _.map(packages, function(package) {
          var latest = package.latest_version;
          if (latest.maintainer.name === name) {
            latest.is_maintainer = true;
          }
          var collaborators = _.filter(latest.collaborators, function(c) {
            return c.name === name;
          });

          if (collaborators.length > 0) {
            latest.is_contributor = true;
          }
          if(!json.email && latest.is_maintainer && latest.maintainer.email) {
            json.email = latest.maintainer.email;
          }
          if(!json.email && collaborators.length > 0 && collaborators[0].email) {
            json.email = collaborators[0].email;
          }
          return latest;
        });
        json.gravatar_url = 'https://www.gravatar.com/avatar/' + md5(_.trim(json.email).toLowerCase());
        json.packages = _.sortBy(json.packages, ['is_maintainer']);

        return res.ok(json, 'collaborator/show.ejs');
      }
    });

  }
};

<|endoftext|>


<commit_before>'use strict';

module.config([
  '$provide', function ($provide) {
    var isCallable = function (fn) {
      angular.isFunction(fn);
    };

    $provide.decorator('$resource', [
      '$delegate', '$cacheFactory', function ($resource, $cacheFactory) {
        return function (url, params, actions, options) {
          if (!angular.isObject(options)) {
            options = {};
          }

          actions = angular.isObject(actions) ? actions : {};
          actions.get = actions.get || {method: 'GET'};
          actions.query = actions.query || {method: 'GET', isArray: true};

          if (options.cache && !options.cache.info) {
            options.cache = options.cache || '$http';
            options.cache = $cacheFactory.get(options.cache) || $cacheFactory(options.cache);
          }

          for (var prop in actions) {
            if (actions.hasOwnProperty(prop) && actions[prop].method.toUpperCase() === 'GET') {
              actions[prop].cache = options.cache;
            }
          }

          var resource = $resource.apply($resource, arguments);

          if (options.cache && options.cache.info) {
            resource.$cache = options.cache;
          }

          return resource;
        }
      }
    ]);
  }
]);<commit_msg>Add missing semi in resourceDecorator<commit_after>'use strict';

module.config([
  '$provide', function ($provide) {
    var isCallable = function (fn) {
      angular.isFunction(fn);
    };

    $provide.decorator('$resource', [
      '$delegate', '$cacheFactory', function ($resource, $cacheFactory) {
        return function (url, params, actions, options) {
          if (!angular.isObject(options)) {
            options = {};
          }

          actions = angular.isObject(actions) ? actions : {};
          actions.get = actions.get || {method: 'GET'};
          actions.query = actions.query || {method: 'GET', isArray: true};

          if (options.cache && !options.cache.info) {
            options.cache = options.cache || '$http';
            options.cache = $cacheFactory.get(options.cache) || $cacheFactory(options.cache);
          }

          for (var prop in actions) {
            if (actions.hasOwnProperty(prop) && actions[prop].method.toUpperCase() === 'GET') {
              actions[prop].cache = options.cache;
            }
          }

          var resource = $resource.apply($resource, arguments);

          if (options.cache && options.cache.info) {
            resource.$cache = options.cache;
          }

          return resource;
        };
      }
    ]);
  }
]);
<|endoftext|>


<commit_before>CKEDITOR.editorConfig = function(config) {
  config.toolbar = [
    { name: 'basicstyles', items: [ 'Bold', 'Italic' ] },
    { name: 'insert', items: [ 'Image' ] },
    { name: 'clipboard', items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
    { name: 'document', items: [ 'Source' ] }
  ];

  config.language = 'pt-BR';
};
<commit_msg>Paste config lines from source code to avoid overriding<commit_after>CKEDITOR.editorConfig = function(config) {
  config.toolbar = [
    { name: 'basicstyles', items: [ 'Bold', 'Italic' ] },
    { name: 'insert', items: [ 'Image' ] },
    { name: 'clipboard', items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
    { name: 'document', items: [ 'Source' ] }
  ];

  config.language = 'pt-BR';

  /* Filebrowser routes */
  // The location of an external file browser, that should be launched when "Browse Server" button is pressed.
  config.filebrowserBrowseUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
  config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";

  // The location of a script that handles file uploads in the Flash dialog.
  config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
  config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
  config.filebrowserImageBrowseUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads in the Image dialog.
  config.filebrowserImageUploadUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads.
  config.filebrowserUploadUrl = "/ckeditor/attachment_files";

  // Rails CSRF token
  config.filebrowserParams = function(){
    var csrf_token, csrf_param, meta,
        metas = document.getElementsByTagName('meta'),
        params = new Object();

    for ( var i = 0 ; i < metas.length ; i++ ){
      meta = metas[i];

      switch(meta.name) {
        case "csrf-token":
          csrf_token = meta.content;
          break;
        case "csrf-param":
          csrf_param = meta.content;
          break;
        default:
          continue;
      }
    }

    if (csrf_param !== undefined && csrf_token !== undefined) {
      params[csrf_param] = csrf_token;
    }

    return params;
  };

  config.addQueryString = function( url, params ){
    var queryString = [];

    if ( !params ) {
      return url;
    } else {
      for ( var i in params )
        queryString.push( i + "=" + encodeURIComponent( params[ i ] ) );
    }

    return url + ( ( url.indexOf( "?" ) != -1 ) ? "&" : "?" ) + queryString.join( "&" );
  };

  // Integrate Rails CSRF token into file upload dialogs (link, image, attachment and flash)
  CKEDITOR.on( 'dialogDefinition', function( ev ){
    // Take the dialog name and its definition from the event data.
    var dialogName = ev.data.name;
    var dialogDefinition = ev.data.definition;
    var content, upload;

    if (CKEDITOR.tools.indexOf(['link', 'image', 'attachment', 'flash'], dialogName) > -1) {
      content = (dialogDefinition.getContents('Upload') || dialogDefinition.getContents('upload'));
      upload = (content == null ? null : content.get('upload'));

      if (upload && upload.filebrowser && upload.filebrowser['params'] === undefined) {
        upload.filebrowser['params'] = config.filebrowserParams();
        upload.action = config.addQueryString(upload.action, upload.filebrowser['params']);
      }
    }
  });
};
<|endoftext|>


<commit_before>//= require libs/GlobalBarHelper.js

'use strict'
window.GOVUK = window.GOVUK || {}

// Bump this if you are releasing a major change to the banner
// This will reset the view count so all users will see the banner, even if previously seen
var BANNER_VERSION = 3;

var globalBarInit = {
  getBannerVersion: function() {
    return BANNER_VERSION
  },

  getLatestCookie: function() {
    var currentCookie = document.cookie.match("(?:^|[ ;])(?:global_bar_seen=)(.+?)(?:(?=;|$))")

    if (currentCookie == null) {
      return currentCookie
    } else {
      return currentCookie[1]
    }
  },

  blacklistedUrl: function() {
    var paths = ["/register-to-vote", "/done", "/brexit", "/get-ready-brexit-check"]

    return new RegExp(paths.join("|")).test(window.location.pathname)
  },

  setBannerCookie: function() {
    var eighty_four_days = 84*24*60*60*1000
    var expiryDate = new Date(Date.now() + eighty_four_days).toUTCString()
    var value = JSON.stringify({count: 0, version: globalBarInit.getBannerVersion()})
    var cookieString = "global_bar_seen=" + value + "; expires=" + expiryDate + ";"

    document.cookie=cookieString
  },

  makeBannerVisible: function() {
    document.documentElement.className = document.documentElement.className.concat(" show-global-bar")
  },

  init: function() {
    if (!globalBarInit.blacklistedUrl()) {
      if (globalBarInit.getLatestCookie() === null) {
        globalBarInit.setBannerCookie()
        globalBarInit.makeBannerVisible()
      } else {
        var currentCookieVersion = parseCookie(globalBarInit.getLatestCookie()).version

        if (currentCookieVersion !== globalBarInit.getBannerVersion()) {
          globalBarInit.setBannerCookie()
        }

        var newCookieCount = parseCookie(globalBarInit.getLatestCookie()).count

        if (newCookieCount < 3) {
          globalBarInit.makeBannerVisible()
        }
      }
    }
  }
}

window.GOVUK.globalBarInit = globalBarInit;
<commit_msg>Change blacklisted Urls for global banner to post 31st<commit_after>//= require libs/GlobalBarHelper.js

'use strict'
window.GOVUK = window.GOVUK || {}

// Bump this if you are releasing a major change to the banner
// This will reset the view count so all users will see the banner, even if previously seen
var BANNER_VERSION = 3;

var globalBarInit = {
  getBannerVersion: function() {
    return BANNER_VERSION
  },

  getLatestCookie: function() {
    var currentCookie = document.cookie.match("(?:^|[ ;])(?:global_bar_seen=)(.+?)(?:(?=;|$))")

    if (currentCookie == null) {
      return currentCookie
    } else {
      return currentCookie[1]
    }
  },

  blacklistedUrl: function() {
    var paths = [
      "/register-to-vote",
      "/done",
      "/transition",
      "/transition-check"
    ]

    return new RegExp(paths.join("|")).test(window.location.pathname)
  },

  setBannerCookie: function() {
    var eighty_four_days = 84*24*60*60*1000
    var expiryDate = new Date(Date.now() + eighty_four_days).toUTCString()
    var value = JSON.stringify({count: 0, version: globalBarInit.getBannerVersion()})
    var cookieString = "global_bar_seen=" + value + "; expires=" + expiryDate + ";"

    document.cookie=cookieString
  },

  makeBannerVisible: function() {
    document.documentElement.className = document.documentElement.className.concat(" show-global-bar")
  },

  init: function() {
    if (!globalBarInit.blacklistedUrl()) {
      if (globalBarInit.getLatestCookie() === null) {
        globalBarInit.setBannerCookie()
        globalBarInit.makeBannerVisible()
      } else {
        var currentCookieVersion = parseCookie(globalBarInit.getLatestCookie()).version

        if (currentCookieVersion !== globalBarInit.getBannerVersion()) {
          globalBarInit.setBannerCookie()
        }

        var newCookieCount = parseCookie(globalBarInit.getLatestCookie()).count

        if (newCookieCount < 3) {
          globalBarInit.makeBannerVisible()
        }
      }
    }
  }
}

window.GOVUK.globalBarInit = globalBarInit;
<|endoftext|>


<commit_before>define(
  ['jquery', 'module'], function ($, module) {
    'use strict';

    var globals = $.extend({}, module.config());
    return globals;
  }
);<commit_msg>smallening globals module<commit_after>define(
  ['module'], function (module) {
    'use strict';

    var globals = module.config();
    return globals;
  }
);<|endoftext|>


<commit_before>/* global HDO */

(function (HDO) {
  HDO.positionsEditor = {
    create: function (url) {
      var instance = Object.create(this);
      instance.url = url;
      return instance;
    },

    init: function (newRowHtml) {
      var self = this, count = 0;

      $('#new-position-button').click(function (e) {
        e.preventDefault();
        console.log(newRowHtml)

        var newId = 'new' + count++;

        $('#positions-table tr:last').after(newRowHtml.replace(/newPosition/g, newId));
        self.initializeMarkdownEditors([newId]);

        $('#position-' + newId + '-parties').chosen();

        $('#destroy-' + newId).click(function () {
          var row = $(this).closest('tr').remove();
          return false;
        });

        return false;
      });

      $('.destroy-position').click(function () {
        var id = $(this).attr('id').split('-')[1];
        $(this).closest('form').append($('<input/>')
          .attr('type', 'hidden')
          .attr('name', 'positions[' + id + '][deleted]')
          .val('true'));

        $(this).closest('tr').remove();

        return false;
      });
    },

    initializeMarkdownEditors: function (positionIds) {
      var i, converter, editor;
      for (i = 0; i < positionIds.length; i++) {
        converter = new Markdown.Converter();
        editor = new Markdown.Editor(converter, "-" + positionIds[i]);
        editor.run();

      }
    }
  };
}(HDO));
<commit_msg>JS lint fixes<commit_after>/* global HDO */

(function (HDO) {
  HDO.positionsEditor = {
    create: function (url) {
      var instance = Object.create(this);
      instance.url = url;
      return instance;
    },

    init: function (newRowHtml) {
      var self = this, count = 0;

      $('#new-position-button').click(function (e) {
        e.preventDefault();

        var newId = 'new' + count++;
        $('#positions-table tr:last').after(newRowHtml.replace(/newPosition/g, newId));
        self.initializeMarkdownEditors([newId]);

        $('#position-' + newId + '-parties').chosen();

        $('#destroy-' + newId).click(function () {
          var row = $(this).closest('tr').remove();
          return false;
        });

        return false;
      });

      $('.destroy-position').click(function () {
        var id = $(this).attr('id').split('-')[1];
        $(this).closest('form').append($('<input/>')
          .attr('type', 'hidden')
          .attr('name', 'positions[' + id + '][deleted]')
          .val('true'));

        $(this).closest('tr').remove();

        return false;
      });
    },

    initializeMarkdownEditors: function (positionIds) {
      var i, converter, editor;
      for (i = 0; i < positionIds.length; i++) {
        converter = new Markdown.Converter();
        editor = new Markdown.Editor(converter, "-" + positionIds[i]);
        editor.run();

      }
    }
  };
}(HDO));
<|endoftext|>


<commit_before>angular.module('Directory.searches.models', ['RailsModel', 'Directory.items.models'])
.factory('Search', ['Model', 'Item', 'Facet',  function (Model, Item, Facet) {
  var Search = Model({url:'/api/search', name: 'search'});

  Search.prototype.lastItemNumber = function () {
    return Math.min(this.page * 25, this.totalHits);
  }

  Search.prototype.firstItemNumber = function () {
    return Math.min((this.page-1)*25 + 1, this.totalHits);
  }

  Search.prototype.hasMoreResults = function () {
    return (this.lastItemNumber() < this.totalHits);
  }

  Search.prototype.facetsAsObjects = function () {
    if (typeof this._facetObjects !== 'undefined') {
      return this._facetObjects;
    }

    this._facetObjects = [];
    angular.forEach(this.facets, function (facet, name) {
      this.push(new Facet(name, facet));
    }, this._facetObjects);

    return this._facetObjects;
  }

  Search.prototype.aFacetIsVisible = function () {
    var aFacetIsVisible = false;
    angular.forEach(this.facetsAsObjects(), function (facet) {
      if (facet.visible())
        aFacetIsVisible = true;
    });
    return aFacetIsVisible;
  }

  return Search;
}])
.factory('Facet', ['Collection', function (Collection) {
  function FacetEntry(name, count, field) {
    this.name = name;
    this.count = count;
    this.field = field;
  }

  FacetEntry.prototype.nameForPresenting = function () {
    return this.name;
  }

  function DateTimeFacetEntry(name, count, field) {
    this.name = name;
    this.count = count;
    this.field = field;
  }

  function ReferenceFacetEntry(model, count, field) {
    this.name = model.id;
    this.model = model;
    this.count = count;
    this.field = field;
  }

  ReferenceFacetEntry.prototype = new FacetEntry();

  DateTimeFacetEntry.prototype = new FacetEntry();

  DateTimeFacetEntry.prototype.nameForPresenting = function () {
    if (!this._date) {
      this._date = new Date(0);
      this._date.setUTCSeconds(this.name/1000);
    }
    if (!this._dateString) {
      if (this._date.getUTCDate() == 1 && this._date.getUTCMonth() == 0) {
        this._dateString = this._date.getUTCFullYear();
      } else if (this._date.getUTCDate() == 1) {
        this._dateString = this._date.getUTCMonth()+1 + "/" + this._date.getUTCFullYear();
      } else {
        this._dateString = this._date.getUTCMonth()+1 + "/" + this._date.getUTCDate() + this.getUTCFullYear();
      }
    }
    return this._dateString;
  }

  ReferenceFacetEntry.prototype.nameForPresenting = function () {
    return this.model.title;
  }

  function Facet(name, options) {
    this.name    = name;
    this.type    = options._type;
    if (this.name == 'collectionId') {
      this.name = "Collection";
      this.type = "reference";
      this.klass = Collection;
    }
    this.data    = options;
  }

  Facet.prototype.visible = function () {
    return (this._entries && this._entries.length >= 1);
  }

  Facet.prototype.entries = function () {
    if (typeof this._entries !== 'undefined') {
      return this._entries;
    }
    this._entries = [];

    var name = this.name;
    switch (this.type) {
    case "terms":
      angular.forEach(this.data.terms, function (term) {
        this.push(new FacetEntry(term.term, term.count, name));
      }, this._entries);
      break;
    case "reference":
      var entries = this._entries;
      angular.forEach(this.data.terms, function (term) {
        this.klass.get(parseInt(term.term)).then(function (model) {
          entries.push(new ReferenceFacetEntry(model, term.count, name.toLowerCase() + "_id"));
        })
      }, this);
    case "date_histogram":
      // angular.forEach(this.data.entries, function(entry) {
      //   this.push(new DateTimeFacetEntry(entry.time, entry.count, name));
      // }, this._entries);
    }

    return this._entries;
  }

  return Facet;
}])
.filter('toItems', ['Item', function (Item) {
  var items = [];
  return function (data, options) {
    items.length = 0;
    if (data) {
      angular.forEach(data, function (result) {
        if (typeof result.$delete !== 'undefined') {
          items.push(result);
        } else {
          items.push(angular.copy(new Item(result), result));
        }
      });
    }
    return items;
  }
}])
.factory('Query', ['$location', function ($location) {

  var getUnique = function(things){
    var u = {}, a = [];
    for(var i = 0, l = things.length; i < l; ++i){
      if(u.hasOwnProperty(things[i])) {
        continue;
      }
      a.push(things[i]);
      u[things[i]] = 1;
    }
    return a;
  }

  function getSearchFromQueryString (queryString) {
    if (typeof queryString !== 'undefined' && queryString !== null) {
      if (angular.isArray(queryString)) {
        return queryString;
      }
      var match = queryString.match(/([^,\"]*\"[^\"]+\"|[^,]+)/g);
      if (match) {
        return getUnique(match);
      } else {
        return [];
      }
    } else {
      return [];
    }
  }

  function Query (queryString) {
    if (angular.isArray(queryString)) {
      this.queryParts = queryString;
      this.updateQueryString();
    } else if (angular.isString(queryString)) {
      this.queryString = queryString;
      this.updateQueryParts();
    } else if (typeof queryString !== 'undefined') {
      var query = Query(queryString.query);
      if (queryString.onQueryBuilt) {
        queryString.onQueryBuilt(query);
      }
      return query;
    } else {
      this.queryString = "";
      this.updateQueryParts();
    }
    this.string = "";
  }

  Query.prototype.updateQueryParts = function () {
    this.queryParts = getSearchFromQueryString(this.queryString);
  }

  Query.prototype.updateQueryString = function () {
    this.queryString = this.queryParts.join(",");
    if (this.queryString == '') {
      this.queryString = null;
    }
  }

  Query.prototype.commit = function () {
    if (this.string && this.string != '') {
      this.queryParts.push(this.string);
      this.string = "";
      this.perform();
    }
  }

  Query.prototype.add = function (thing) {
    this.queryParts.push(thing);
    this.perform();
  }

  Query.prototype.remove = function (thing) {
    this.queryParts.splice(this.queryParts.indexOf(thing), 1);
    this.perform();
  }

  Query.prototype.perform = function () {
      this.updateQueryString();
      $location.search('page', 1);
      $location.search('query', this.queryString);
  }

  Query.prototype.toSearchQuery = function () {
    var string = this.queryParts.join(" AND ");
    if (string == '') {
      return null;
    }
    return string;
  }

  return Query;
}]);
<commit_msg>handle null queries<commit_after>angular.module('Directory.searches.models', ['RailsModel', 'Directory.items.models'])
.factory('Search', ['Model', 'Item', 'Facet',  function (Model, Item, Facet) {
  var Search = Model({url:'/api/search', name: 'search'});

  Search.prototype.lastItemNumber = function () {
    return Math.min(this.page * 25, this.totalHits);
  }

  Search.prototype.firstItemNumber = function () {
    return Math.min((this.page-1)*25 + 1, this.totalHits);
  }

  Search.prototype.hasMoreResults = function () {
    return (this.lastItemNumber() < this.totalHits);
  }

  Search.prototype.facetsAsObjects = function () {
    if (typeof this._facetObjects !== 'undefined') {
      return this._facetObjects;
    }

    this._facetObjects = [];
    angular.forEach(this.facets, function (facet, name) {
      this.push(new Facet(name, facet));
    }, this._facetObjects);

    return this._facetObjects;
  }

  Search.prototype.aFacetIsVisible = function () {
    var aFacetIsVisible = false;
    angular.forEach(this.facetsAsObjects(), function (facet) {
      if (facet.visible())
        aFacetIsVisible = true;
    });
    return aFacetIsVisible;
  }

  return Search;
}])
.factory('Facet', ['Collection', function (Collection) {
  function FacetEntry(name, count, field) {
    this.name = name;
    this.count = count;
    this.field = field;
  }

  FacetEntry.prototype.nameForPresenting = function () {
    return this.name;
  }

  function DateTimeFacetEntry(name, count, field) {
    this.name = name;
    this.count = count;
    this.field = field;
  }

  function ReferenceFacetEntry(model, count, field) {
    this.name = model.id;
    this.model = model;
    this.count = count;
    this.field = field;
  }

  ReferenceFacetEntry.prototype = new FacetEntry();

  DateTimeFacetEntry.prototype = new FacetEntry();

  DateTimeFacetEntry.prototype.nameForPresenting = function () {
    if (!this._date) {
      this._date = new Date(0);
      this._date.setUTCSeconds(this.name/1000);
    }
    if (!this._dateString) {
      if (this._date.getUTCDate() == 1 && this._date.getUTCMonth() == 0) {
        this._dateString = this._date.getUTCFullYear();
      } else if (this._date.getUTCDate() == 1) {
        this._dateString = this._date.getUTCMonth()+1 + "/" + this._date.getUTCFullYear();
      } else {
        this._dateString = this._date.getUTCMonth()+1 + "/" + this._date.getUTCDate() + this.getUTCFullYear();
      }
    }
    return this._dateString;
  }

  ReferenceFacetEntry.prototype.nameForPresenting = function () {
    return this.model.title;
  }

  function Facet(name, options) {
    this.name    = name;
    this.type    = options._type;
    if (this.name == 'collectionId') {
      this.name = "Collection";
      this.type = "reference";
      this.klass = Collection;
    }
    this.data    = options;
  }

  Facet.prototype.visible = function () {
    return (this._entries && this._entries.length >= 1);
  }

  Facet.prototype.entries = function () {
    if (typeof this._entries !== 'undefined') {
      return this._entries;
    }
    this._entries = [];

    var name = this.name;
    switch (this.type) {
    case "terms":
      angular.forEach(this.data.terms, function (term) {
        this.push(new FacetEntry(term.term, term.count, name));
      }, this._entries);
      break;
    case "reference":
      var entries = this._entries;
      angular.forEach(this.data.terms, function (term) {
        this.klass.get(parseInt(term.term)).then(function (model) {
          entries.push(new ReferenceFacetEntry(model, term.count, name.toLowerCase() + "_id"));
        })
      }, this);
    case "date_histogram":
      // angular.forEach(this.data.entries, function(entry) {
      //   this.push(new DateTimeFacetEntry(entry.time, entry.count, name));
      // }, this._entries);
    }

    return this._entries;
  }

  return Facet;
}])
.filter('toItems', ['Item', function (Item) {
  var items = [];
  return function (data, options) {
    items.length = 0;
    if (data) {
      angular.forEach(data, function (result) {
        if (typeof result.$delete !== 'undefined') {
          items.push(result);
        } else {
          items.push(angular.copy(new Item(result), result));
        }
      });
    }
    return items;
  }
}])
.factory('Query', ['$location', function ($location) {

  var getUnique = function(things){
    var u = {}, a = [];
    for(var i = 0, l = things.length; i < l; ++i){
      if(u.hasOwnProperty(things[i])) {
        continue;
      }
      a.push(things[i]);
      u[things[i]] = 1;
    }
    return a;
  }

  function getSearchFromQueryString (queryString) {
    if (typeof queryString !== 'undefined' && queryString !== null) {
      if (angular.isArray(queryString)) {
        return queryString;
      }
      var match = queryString.match(/([^,\"]*\"[^\"]+\"|[^,]+)/g);
      if (match) {
        return getUnique(match);
      } else {
        return [];
      }
    } else {
      return [];
    }
  }

  function Query (queryString) {
    if (angular.isArray(queryString)) {
      this.queryParts = queryString;
      this.updateQueryString();
    } else if (angular.isString(queryString)) {
      this.queryString = queryString;
      this.updateQueryParts();
    } else if (typeof queryString !== 'undefined' && queryString != null) {
      var query = Query(queryString.query);
      if (queryString.onQueryBuilt) {
        queryString.onQueryBuilt(query);
      }
      return query;
    } else {
      this.queryString = "";
      this.updateQueryParts();
    }
    this.string = "";
  }

  Query.prototype.updateQueryParts = function () {
    this.queryParts = getSearchFromQueryString(this.queryString);
  }

  Query.prototype.updateQueryString = function () {
    this.queryString = this.queryParts.join(",");
    if (this.queryString == '') {
      this.queryString = null;
    }
  }

  Query.prototype.commit = function () {
    if (this.string && this.string != '') {
      this.queryParts.push(this.string);
      this.string = "";
      this.perform();
    }
  }

  Query.prototype.add = function (thing) {
    this.queryParts.push(thing);
    this.perform();
  }

  Query.prototype.remove = function (thing) {
    this.queryParts.splice(this.queryParts.indexOf(thing), 1);
    this.perform();
  }

  Query.prototype.perform = function () {
      this.updateQueryString();
      $location.search('page', 1);
      $location.search('query', this.queryString);
  }

  Query.prototype.toSearchQuery = function () {
    var string = this.queryParts.join(" AND ");
    if (string == '') {
      return null;
    }
    return string;
  }

  return Query;
}]);
<|endoftext|>


<commit_before>/**
 * Funcion para atachar que una caja de texto tenga funcionamiento con soulmate y redis
 * @param tipo_busqueda
 */
var soulmateAsigna = function(tipo_busqueda, elem)
{
    if (elem == undefined)
        var elemento = 'nombre';
    else
        var elemento = elem;

    var render = function(term, data, type, index, id)
    {
        if (I18n.locale == 'es-cientifico')
        {
            var nombres = '
 ' + data.nombre_comun + '
' + '
' + data.nombre_cientifico + ' ' + data.autoridad + '

';
            return nombres;
        }else{
            data.nombre_cientifico = limpiar(data.nombre_cientifico);

            if(data.nombre_comun == null) {
                var nombres = '' + data.nombre_cientifico + '';
            }else {
                var nombres = '' + primeraEnMayuscula(data.nombre_comun) + ' ' + data.lengua + '' + data.nombre_cientifico + '';
            }

            if(data.foto == null) {
                var foto = '';
            }else{
                var foto_url = data.foto;
                var foto = "";
            }

            var iconos = "";
            var ev = '-ev-icon';

            $.each(data.cons_amb_dist, function(i, val){
                if (i == 'no-endemica' || i =='actual') return true;
                iconos = iconos + ""
            });

            if(data.geodatos != undefined && data.geodatos.length > 0){
                iconos = iconos + "";
            }

            if(data.fotos > 0) {
                iconos = iconos + "" + data.fotos + "";
            }

            return foto + " " + nombres + "
" + iconos + "
";
        }
    };

    var select = function(term, data, type)
    {
        $('#' + elemento).val(term);
        $('ul#soulmate').hide();    // esconde el autocomplete cuando escoge uno

        switch (tipo_busqueda){
            case 'avanzada':
                cat_tax_asociadas(data.id);  // despliega las categorias taxonomicas asociadas al taxon
                $('#id').attr('value', data.id); //TODO arreglar el ID id ¬.¬ !>.> pffff
                break;
            case 'peces':
                $('#id').attr('value', data.id);
                bloqueaBusqueda();
                break;
            case 'pmc_new':
                $('#pmc_pez_especie_id').attr('value', data.id);
                break;
            case 'soloAsigna':
                $('#id').attr('value', data.id); //TODO arreglar el ID id ¬.¬ !>.> pffff
                break;
            case 'metamares':
                $('#proy_b_especie_id').attr('value', data.id); // feliz?
                break;
            case 'metamares_proy_esp':
                $('#'+elemento.replace('nombre_cientifico','especie_id')).attr('value', data.id);
                break;
            default:
                // Para no pasar por el controlador de busquedas, ir directo a la especie, solo busqueda basica
                var nom_cientifico = data.nombre_cientifico.trim().toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/(^-|-$)/g,'').replace(/[\(\)]/g, '');
                window.location.replace('/especies/'  + data.id + '-' + nom_cientifico);
                $('#id').attr('value', data.id); //TODO arreglar el ID id ¬.¬ !>.> pffff
        }
    };

    $('#' + elemento).soulmate({
        url:            "http://"+ IP + ":" + PORT + "sm/search",
        types:          TYPES,
        renderCallback: render,
        selectCallback: select,
        minQueryLength: 2,
        maxResults:     5,
        timeout:        3500
    });
};<commit_msg>actualizado icono de globo para b4<commit_after>/**
 * Funcion para atachar que una caja de texto tenga funcionamiento con soulmate y redis
 * @param tipo_busqueda
 */
var soulmateAsigna = function(tipo_busqueda, elem)
{
    if (elem == undefined)
        var elemento = 'nombre';
    else
        var elemento = elem;

    var render = function(term, data, type, index, id)
    {
        if (I18n.locale == 'es-cientifico')
        {
            var nombres = '
 ' + data.nombre_comun + '
' + '
' + data.nombre_cientifico + ' ' + data.autoridad + '

';
            return nombres;
        }else{
            data.nombre_cientifico = limpiar(data.nombre_cientifico);

            if(data.nombre_comun == null) {
                var nombres = '' + data.nombre_cientifico + '';
            }else {
                var nombres = '' + primeraEnMayuscula(data.nombre_comun) + ' ' + data.lengua + '' + data.nombre_cientifico + '';
            }

            if(data.foto == null) {
                var foto = '';
            }else{
                var foto_url = data.foto;
                var foto = "";
            }

            var iconos = "";
            var ev = '-ev-icon';

            $.each(data.cons_amb_dist, function(i, val){
                if (i == 'no-endemica' || i =='actual') return true;
                iconos = iconos + ""
            });

            if(data.geodatos != undefined && data.geodatos.length > 0){
                iconos = iconos + "";
            }

            if(data.fotos > 0) {
                iconos = iconos + "" + data.fotos + "";
            }

            return foto + " " + nombres + "
" + iconos + "
";
        }
    };

    var select = function(term, data, type)
    {
        $('#' + elemento).val(term);
        $('ul#soulmate').hide();    // esconde el autocomplete cuando escoge uno

        switch (tipo_busqueda){
            case 'avanzada':
                cat_tax_asociadas(data.id);  // despliega las categorias taxonomicas asociadas al taxon
                $('#id').attr('value', data.id); //TODO arreglar el ID id ¬.¬ !>.> pffff
                break;
            case 'peces':
                $('#id').attr('value', data.id);
                bloqueaBusqueda();
                break;
            case 'pmc_new':
                $('#pmc_pez_especie_id').attr('value', data.id);
                break;
            case 'soloAsigna':
                $('#id').attr('value', data.id); //TODO arreglar el ID id ¬.¬ !>.> pffff
                break;
            case 'metamares':
                $('#proy_b_especie_id').attr('value', data.id); // feliz?
                break;
            case 'metamares_proy_esp':
                $('#'+elemento.replace('nombre_cientifico','especie_id')).attr('value', data.id);
                break;
            default:
                // Para no pasar por el controlador de busquedas, ir directo a la especie, solo busqueda basica
                var nom_cientifico = data.nombre_cientifico.trim().toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/(^-|-$)/g,'').replace(/[\(\)]/g, '');
                window.location.replace('/especies/'  + data.id + '-' + nom_cientifico);
                $('#id').attr('value', data.id); //TODO arreglar el ID id ¬.¬ !>.> pffff
        }
    };

    $('#' + elemento).soulmate({
        url:            "http://"+ IP + ":" + PORT + "sm/search",
        types:          TYPES,
        renderCallback: render,
        selectCallback: select,
        minQueryLength: 2,
        maxResults:     5,
        timeout:        3500
    });
};<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name MatchCalendarApp.controller:PostGeneratorCtrl
 * @description
 * # PostGeneratorCtrl
 * Controller of the MatchCalendarApp
 */
angular.module('MatchCalendarApp')
    .controller('PostGeneratorCtrl', [
           '$scope', '$window', '$state', '$interpolate', '$modal', '$localForage', 'PostGeneratorRegions', 'PostGeneratorGameType', 'DateTimeService', 'Templates', 'Subreddits', function (
            $scope,   $window,   $state,   $interpolate,   $modal,   $localForage,   PostGeneratorRegions,   PostGeneratorGameType,   DateTimeService,   Templates,   Subreddits) {
        $scope.regions = PostGeneratorRegions;
        $scope.gameTypes = PostGeneratorGameType.types;
        $scope.DateTime = DateTimeService;
        $scope.templates = Templates;
        $scope.subreddits = Subreddits;

        // generator information
        $scope.generator = {
            postTitle: 'Game Title',
            region: 'NA',
            gameType: 'FFA',
            gameTypeData: [],
            scenarios: ['Vanilla']
        };

        if (Templates.customTemplates[0]) {
            $scope.generator.template = Templates.customTemplates[0].name;
        }

        $scope.$watch('generator.gameType', function(newValue, oldValue) {
            if (oldValue === newValue) return;

            $scope.generator.gameTypeData = PostGeneratorGameType.types[newValue].defaultValues();
        });

        // save and load the generator settings
        $localForage.bind($scope, 'generator');

        // set the opening time to the current time for easy use
        $scope.opens = DateTimeService.currentTime();

        // minimum time for things to show
        $scope.minTime = DateTimeService.currentTime();

        $scope.addScenario = function (name) {
            if (name === '' || name === null || name === undefined) return;

            if ($scope.generator.scenarios.indexOf(name) === -1) {
                $scope.generator.scenarios.push(name);
            }
        };

        $scope.removeScenario = function (index) {
            $scope.generator.scenarios.splice(index, 1);

            if ($scope.generator.scenarios.length === 0) {
                $scope.generator.scenarios.push('Vanilla');
            }
        };

        $scope.validTemplate = function() {
            return $scope.generator.template && Templates.customTemplateExists($scope.generator.template);
        };

        $scope.validSubreddit = function() {
            return $scope.generator.subreddit && Subreddits.subreddits.indexOf($scope.generator.subreddit) !== -1;
        };

        $scope.buildTitle = function() {
            return DateTimeService.format(DateTimeService.formats.REDDIT_POST, $scope.opens.utc(), true) +
                    ' - ' +
                    $scope.generator.region +
                    ' - ' +
                    $scope.generator.postTitle +
                    ' - ' +
                    PostGeneratorGameType.types[$scope.generator.gameType].format($scope.generator.gameTypeData) +
                    ' - ' +
                    $scope.generator.scenarios.join(', ');
        };

        var templateVariables = {
            get opensUTC() {
                return DateTimeService.format(DateTimeService.formats.REDDIT_POST, $scope.opens, true);
            },
            get title() {
                return $scope.generator.postTitle;
            },
            get region() {
                return $scope.generator.region;
            },
            get teams() {
                return PostGeneratorGameType.types[$scope.generator.gameType].format($scope.generator.gameTypeData);
            },
            get scenarios() {
                return $scope.generator.scenarios.join(', ');
            },
            get DateTime() {
                return DateTimeService;
            }
        };

        /**
         * opens a new window to create a reddit post with the compiled template and info included
         */
        $scope.openReddit = function() {
            var generated = Templates.compileTemplate($scope.generator.template, templateVariables);

            $window.open(
                'https://reddit.com/r/' + $scope.generator.subreddit + '/submit?title=' +
                    encodeURIComponent($scope.buildTitle()) +
                    '&text=' +
                    encodeURIComponent(generated) +
                    encodeURIComponent('\n\n*^created ^using ^the [^Match ^Calendar](' + $window.location.protocol + '//' + $window.location.host + ')*'),
                '_blank');
        };
    }]);
<commit_msg>feat(PostGenerator): set to the first subreddit/template if they exist<commit_after>'use strict';

/**
 * @ngdoc function
 * @name MatchCalendarApp.controller:PostGeneratorCtrl
 * @description
 * # PostGeneratorCtrl
 * Controller of the MatchCalendarApp
 */
angular.module('MatchCalendarApp')
    .controller('PostGeneratorCtrl', [
           '$scope', '$window', '$state', '$interpolate', '$modal', '$localForage', 'PostGeneratorRegions', 'PostGeneratorGameType', 'DateTimeService', 'Templates', 'Subreddits', function (
            $scope,   $window,   $state,   $interpolate,   $modal,   $localForage,   PostGeneratorRegions,   PostGeneratorGameType,   DateTimeService,   Templates,   Subreddits) {
        $scope.regions = PostGeneratorRegions;
        $scope.gameTypes = PostGeneratorGameType.types;
        $scope.DateTime = DateTimeService;
        $scope.templates = Templates;
        $scope.subreddits = Subreddits;

        // generator information
        $scope.generator = {
            postTitle: 'Game Title',
            region: 'NA',
            gameType: 'FFA',
            gameTypeData: [],
            scenarios: ['Vanilla'],
            subreddit: Subreddits.subreddits[0] || null,
            template: Templates.customTemplates[0] ? Templates.customTemplates[0].name : null
        };

        if (Templates.customTemplates[0]) {
            $scope.generator.template = Templates.customTemplates[0].name;
        }

        $scope.$watch('generator.gameType', function(newValue, oldValue) {
            if (oldValue === newValue) return;

            $scope.generator.gameTypeData = PostGeneratorGameType.types[newValue].defaultValues();
        });

        // save and load the generator settings
        $localForage.bind($scope, 'generator');

        // set the opening time to the current time for easy use
        $scope.opens = DateTimeService.currentTime();

        // minimum time for things to show
        $scope.minTime = DateTimeService.currentTime();

        $scope.addScenario = function (name) {
            if (name === '' || name === null || name === undefined) return;

            if ($scope.generator.scenarios.indexOf(name) === -1) {
                $scope.generator.scenarios.push(name);
            }
        };

        $scope.removeScenario = function (index) {
            $scope.generator.scenarios.splice(index, 1);

            if ($scope.generator.scenarios.length === 0) {
                $scope.generator.scenarios.push('Vanilla');
            }
        };

        $scope.validTemplate = function() {
            return $scope.generator.template && Templates.customTemplateExists($scope.generator.template);
        };

        $scope.validSubreddit = function() {
            return $scope.generator.subreddit && Subreddits.subreddits.indexOf($scope.generator.subreddit) !== -1;
        };

        $scope.buildTitle = function() {
            return DateTimeService.format(DateTimeService.formats.REDDIT_POST, $scope.opens.utc(), true) +
                    ' - ' +
                    $scope.generator.region +
                    ' - ' +
                    $scope.generator.postTitle +
                    ' - ' +
                    PostGeneratorGameType.types[$scope.generator.gameType].format($scope.generator.gameTypeData) +
                    ' - ' +
                    $scope.generator.scenarios.join(', ');
        };

        var templateVariables = {
            get opensUTC() {
                return DateTimeService.format(DateTimeService.formats.REDDIT_POST, $scope.opens, true);
            },
            get title() {
                return $scope.generator.postTitle;
            },
            get region() {
                return $scope.generator.region;
            },
            get teams() {
                return PostGeneratorGameType.types[$scope.generator.gameType].format($scope.generator.gameTypeData);
            },
            get scenarios() {
                return $scope.generator.scenarios.join(', ');
            },
            get DateTime() {
                return DateTimeService;
            }
        };

        /**
         * opens a new window to create a reddit post with the compiled template and info included
         */
        $scope.openReddit = function() {
            var generated = Templates.compileTemplate($scope.generator.template, templateVariables);

            $window.open(
                'https://reddit.com/r/' + $scope.generator.subreddit + '/submit?title=' +
                    encodeURIComponent($scope.buildTitle()) +
                    '&text=' +
                    encodeURIComponent(generated) +
                    encodeURIComponent('\n\n*^created ^using ^the [^Match ^Calendar](' + $window.location.protocol + '//' + $window.location.host + ')*'),
                '_blank');
        };
    }]);
<|endoftext|>


<commit_before>import Ember from 'ember';

const get = Ember.get;
const set = Ember.set;
const {
  Component
} = Ember;

export default Component.extend({
  classNames: [ 'sideBar', 'sideBar__escaped' ],
  cardTypes: [
    {
      name: 'Forms',
      isExpanded: false,
      cards: [
        {
          name: 'Mailchimp',
          type: 'form',
          imageUrl: 'assets/images/card-mailchimp.png',
          showName: false
        }
      ]
    },
    {
      name: 'Video',
      isExpanded: false,
      cards: [
        {
          name: 'Vimeo',
          type: 'video',
          imageUrl: 'assets/images/card-vimeo.png',
          showName: false
        },
        {
          name: 'YouTube',
          type: 'video',
          imageUrl: 'assets/images/card-youtube.png',
          showName: false
        }
      ]
    },
    {
      name: 'Images',
      isExpanded: false,
      cards: [
        {
          name: 'Background Slideshow',
          type: 'image',
          imageUrl: 'assets/images/card-background-slideshow.png',
          showName: true
        },
        {
          name: 'Image',
          type: 'image',
          imageUrl: 'assets/images/card-image.png',
          showName: true
        }
      ]
    },
    {
      name: 'Text',
      isExpanded: false,
      cards: [
        {
          name: 'Bullet Points',
          type: 'text',
          imageUrl: 'assets/images/card-bullet-points.png',
          showName: true
        },
        {
          name: 'Plain Text',
          type: 'text',
          imageUrl: 'assets/images/card-plain-text.png',
          showName: true
        }
      ]
    },
    {
      name: 'Code',
      isExpanded: false,
      cards: [
        {
          name: 'Codepen',
          type: 'code',
          imageUrl: 'assets/images/card-codepen.png',
          showName: false
        }
      ]
    }
  ],

  actions: {
    toggleCardTypeVisibility(index) {
      const cardTypes = get(this, 'cardTypes');
      const cardType = cardTypes[index];
      const isCardTypeExpanded = get(cardType, 'isExpanded');

      cardTypes.setEach('isExpanded', false);
      set(cardType, 'isExpanded', !isCardTypeExpanded);
    },

    addCardToTemplate(card) {
      this.sendAction('addCard', card);
    },

    toggleSlotSelection(card) {
      this.sendAction('toggleSlotSelection', card);
    }
  }
});
<commit_msg>Updated temp card data to include description for card.<commit_after>import Ember from 'ember';

const get = Ember.get;
const set = Ember.set;
const {
  Component
} = Ember;

export default Component.extend({
  classNames: [ 'sideBar', 'sideBar__escaped' ],
  cardTypes: [
    {
      name: 'Forms',
      isExpanded: false,
      cards: [
        {
          name: 'Mailchimp',
          description: 'Newsletter management',
          type: 'form',
          thumbnail: 'assets/images/card-mailchimp.png',
          showName: false
        }
      ]
    },
    {
      name: 'Video',
      isExpanded: false,
      cards: [
        {
          name: 'Vimeo',
          description: 'Video hosting for creators',
          type: 'video',
          thumbnail: 'assets/images/card-vimeo.png',
          showName: false
        },
        {
          name: 'YouTube',
          description: 'Hosts user-generated videos',
          type: 'video',
          thumbnail: 'assets/images/card-youtube.png',
          showName: false
        }
      ]
    },
    {
      name: 'Images',
      isExpanded: false,
      cards: [
        {
          name: 'Background Slideshow',
          description: 'Rotating hero images',
          type: 'image',
          thumbnail: 'assets/images/card-background-slideshow.png',
          showName: true
        },
        {
          name: 'Image',
          description: 'Link to and import any image',
          type: 'image',
          thumbnail: 'assets/images/card-image.png',
          showName: true
        }
      ]
    },
    {
      name: 'Text',
      isExpanded: false,
      cards: [
        {
          name: 'Bullet Points',
          description: 'Create an ordered list of images and/or text',
          type: 'text',
          thumbnail: 'assets/images/card-bullet-points.png',
          showName: true
        },
        {
          name: 'Plain Text',
          description: 'Just a plain bit of text',
          type: 'text',
          thumbnail: 'assets/images/card-plain-text.png',
          showName: true
        }
      ]
    },
    {
      name: 'Code',
      isExpanded: false,
      cards: [
        {
          name: 'Codepen',
          description: 'Front End Developer Playground & Code Editor',
          type: 'code',
          thumbnail: 'assets/images/card-codepen.png',
          showName: false
        }
      ]
    }
  ],

  actions: {
    toggleCardTypeVisibility(index) {
      const cardTypes = get(this, 'cardTypes');
      const cardType = cardTypes[index];
      const isCardTypeExpanded = get(cardType, 'isExpanded');

      cardTypes.setEach('isExpanded', false);
      set(cardType, 'isExpanded', !isCardTypeExpanded);
    },

    addCardToTemplate(card) {
      this.sendAction('addCard', card);
    },

    toggleSlotSelection(card) {
      this.sendAction('toggleSlotSelection', card);
    }
  }
});
<|endoftext|>


<commit_before>(function () {

  angular
    .module('fmsc')
    .component('donate', {
      controller: donateController,
      templateUrl: 'donate/donate.html'
    });

  function donateController($rootScope, $log, Firebase, DEBUGFirebaseURL, _) {
    const vm = this;
    const _ref = new Firebase(DEBUGFirebaseURL);

    let _imageId = null;

    vm.data = {};
    vm.donate = donate;
    vm.reservedPieces = [];
    vm.availablePieces = [];

    init();

    function donate() {
      $log.debug('donating...');

      getNewReservedPieces().then((newPieces) => {

        const invoice = {};
        invoice.state = vm.data.state;
        invoice.name = vm.data.name;
        invoice.user = 'user';
        invoice.reserved_time = Date.now();
        invoice.pieces = {};

        for (let i = 0; i < newPieces.length; i++) {
          invoice.pieces[newPieces[i]] = true;
        }

        _ref.child('invoices').push(invoice);
        _ref.child(`images/${_imageId}/pieces_reserved`).update(invoice.pieces);

        $log.debug('Invoice');
        $log.debug(invoice);
      });
    }

    function init() {
      getImageID();
    }

    function getImageID() {
      _ref.child('current_image').on('value', (snap) => {
        _imageId = snap.val();
        $log.debug(`Image ID: ${_imageId}`);

        getAvailablePieces();
        getReservedPieces();
      });
    }

    function getAvailablePieces() {
      _ref.child(`images/${_imageId}/pieces_available`).on('value',
        (snapshot) => {
          vm.availablePieces = (snapshot.val() === null)
                             ? [] : Object.keys(snapshot.val());

          $log.debug('Available Pieces');
          $log.debug(vm.availablePieces);

          refresh();
        });
    }

    function getReservedPieces() {
      _ref.child(`images/${_imageId}/pieces_reserved`).on('value',
        (snapshot) => {
          vm.reservedPieces = (snapshot.val() === null)
                            ? [] : Object.keys(snapshot.val());

          $log.debug('Reserved Pieces');
          $log.debug(vm.reservedPieces);

          refresh();
        });
    }

    function removePiece() {
      const newPiece = _.sample(vm.availablePieces);

      // TODO: infinite loop
      return _ref.child(`images/${_imageId}/pieces_available/${newPiece}`)
        .remove()
        .then(() => newPiece)
        .catch(() => removePiece());
    }

    function getNewReservedPieces() {
      const removePromises = [];

      for (let i = 0; i < vm.data.quantity; i++) {
        removePromises.push(removePiece());
      }

      return Promise.all(removePromises);
    }

    function refresh() {
      if (!$rootScope.$$phase) {
        $rootScope.$digest();
      }
    }
  }

})();
<commit_msg>Added invoice id to pieces<commit_after>(function () {

  angular
    .module('fmsc')
    .component('donate', {
      controller: donateController,
      templateUrl: 'donate/donate.html'
    });

  function donateController($rootScope, $log, Firebase, DEBUGFirebaseURL, _) {
    const vm = this;
    const _ref = new Firebase(DEBUGFirebaseURL);

    let _imageId = null;

    vm.data = {};
    vm.donate = donate;
    vm.reservedPieces = [];
    vm.availablePieces = [];

    init();

    function donate() {
      $log.debug('donating...');

      getNewReservedPieces().then((newPieces) => {

        const invoice = {};
        invoice.state = vm.data.state;
        invoice.name = vm.data.name;
        invoice.user = 'user';
        invoice.reserved_time = Date.now();
        invoice.pieces = {};

        for (let i = 0; i < newPieces.length; i++) {
          invoice.pieces[newPieces[i]] = true;
        }

        _ref.child('invoices').push(invoice).then((i) => {
          for (let j = 0; j < newPieces.length; j++) {
            $log.debug(`update piece ${newPieces[j]} with invoice ${i.key()}`);

            _ref.child(`pieces/${newPieces[j]}`).update({
              invoice: i.key()
            });
          }
        });

        _ref.child(`images/${_imageId}/pieces_reserved`).update(invoice.pieces);

        $log.debug('Invoice');
        $log.debug(invoice);
      });
    }

    function init() {
      getImageID();
    }

    function getImageID() {
      _ref.child('current_image').on('value', (snap) => {
        _imageId = snap.val();
        $log.debug(`Image ID: ${_imageId}`);

        getAvailablePieces();
        getReservedPieces();
      });
    }

    function getAvailablePieces() {
      _ref.child(`images/${_imageId}/pieces_available`).on('value',
        (snapshot) => {
          vm.availablePieces = (snapshot.val() === null)
                             ? [] : Object.keys(snapshot.val());

          $log.debug('Available Pieces');
          $log.debug(vm.availablePieces);

          refresh();
        });
    }

    function getReservedPieces() {
      _ref.child(`images/${_imageId}/pieces_reserved`).on('value',
        (snapshot) => {
          vm.reservedPieces = (snapshot.val() === null)
                            ? [] : Object.keys(snapshot.val());

          $log.debug('Reserved Pieces');
          $log.debug(vm.reservedPieces);

          refresh();
        });
    }

    function removePiece() {
      const newPiece = _.sample(vm.availablePieces);

      // TODO: infinite loop
      return _ref.child(`images/${_imageId}/pieces_available/${newPiece}`)
        .remove()
        .then(() => newPiece)
        .catch(() => removePiece());
    }

    function getNewReservedPieces() {
      const removePromises = [];

      for (let i = 0; i < vm.data.quantity; i++) {
        removePromises.push(removePiece());
      }

      return Promise.all(removePromises);
    }

    function refresh() {
      if (!$rootScope.$$phase) {
        $rootScope.$digest();
      }
    }
  }

})();
<|endoftext|>