You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ol...@apache.org on 2016/04/09 12:15:17 UTC
[21/61] [abbrv] [partial] ambari git commit: AMBARI-15679. Initial
commit for LogSearch service definition (oleewre)
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.js
new file mode 100644
index 0000000..e65e8cd
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.js
@@ -0,0 +1,1045 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory(require("_"), require("jQuery"), require("Backbone"), require("Backgrid"));
+ else if(typeof define === 'function' && define.amd)
+ define(["underscore", "jquery", "backbone", "backgrid"], factory);
+ else if(typeof exports === 'object')
+ exports["Backgrid.Extension.ColumnManager"] = factory(require("_"), require("jQuery"), require("Backbone"), require("Backgrid"));
+ else
+ root["Backgrid.Extension.ColumnManager"] = factory(root["_"], root["jQuery"], root["Backbone"], root["Backgrid"]);
+})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__) {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId])
+/******/ return installedModules[moduleId].exports;
+
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ exports: {},
+/******/ id: moduleId,
+/******/ loaded: false
+/******/ };
+
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+
+/******/ // Flag the module as loaded
+/******/ module.loaded = true;
+
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+
+
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+ /**
+ * A column manager for backgrid
+ *
+ * @module Backgrid.ColumnManager
+ */
+ // Dependencies
+ var _ = __webpack_require__(1);
+ var $ = __webpack_require__(2);
+ var Backbone = __webpack_require__(3);
+ var Backgrid = __webpack_require__(4);
+
+ /**
+ * Manages visibility of columns.
+ *
+ * @class Backgrid.Extension.ColumnManager ColumnManager
+ * @constructor
+ * @param {Backgrid.Columns} columns
+ * @param {Object} [options]
+ * @param {number} [options.initialColumnCount] Initial amount of columns to show. Default is null (All visible).
+ * @param {boolean} [options.trackSize]
+ * @param {boolean} [options.trackOrder]
+ * @param {boolean} [options.trackVisibility]
+ * @param {string} [options.stateChecking] can be "strict" or "loose".
+ * @param {boolean} [options.saveState]
+ * @param {string} [options.saveStateKey] Storage key. Must be unique for location. Can be left out if this plugin is only used in one place.
+ * @param {string} [options.saveStateLocation] Can be "localStorage" (default) or "sessionStorage" (be aware, session stored values are lost when window is closed)
+ * @param {boolean} [options.loadStateOnInit]
+ * @param {Array} [state]
+ */
+ Backgrid.Extension.ColumnManager = function (columns, options, state) {
+ // Bind backbone events
+ _.extend(this, Backbone.Events);
+
+ // Save options and merge with defaults
+ var defaults = {
+ initialColumnsVisible: null,
+
+ // State options
+ trackSize: true,
+ trackOrder: true,
+ trackVisibility: true,
+ stateChecking: "strict",
+ saveState: false,
+ saveStateKey: "",
+ saveStateLocation: "localStorage",
+ loadStateOnInit: false
+ };
+ this.options = _.extend({}, defaults, options);
+ this.state = [];
+
+ // Check if columns is instance of Backgrid.Columns
+ if (columns instanceof Backgrid.Columns) {
+ // Save columns
+ this.columns = columns;
+
+ // Add columnManager to columns (instance)
+ columns.columnManager = this;
+ this.addManagerToColumns();
+
+ // Set state if provided
+ var storedState = (this.options.loadStateOnInit) ? this.loadState() : false;
+ if (state && this.checkStateValidity(state)) {
+ this.setState(state, true);
+ }
+ else if (storedState) {
+ this.setState(storedState, true);
+ }
+ else {
+ // If no initial state is provided, adhere to initial column visibility settings
+ this.setInitialColumnVisibility();
+
+ // Set current state
+ this.setState(this.getStateFromColumns());
+ }
+
+ // Listen to column events
+ if (this.options.trackVisibility || this.options.trackSize || this.options.trackOrder) {
+ //this.stateUpdateHandler = _.bind(this.stateUpdateHandler, this);
+ var events = "" +
+ ((this.options.trackVisibility) ? "change:renderable " : "") +
+ ((this.options.trackSize) ? "resize " : "") +
+ ((this.options.trackOrder) ? "ordered" : "");
+ this.columns.on(events, _.bind(this.stateUpdateHandler, this));
+ }
+ }
+ else {
+ // Issue warning
+ console.error("Backgrid.ColumnManager: options.columns is not an instance of Backgrid.Columns");
+ }
+ };
+
+ /**
+ * Loops over all columns and sets the visibility according to provided options.
+ *
+ * @method setInitialColumnVisibility
+ */
+ Backgrid.Extension.ColumnManager.prototype.setInitialColumnVisibility = function () {
+ var self = this;
+
+ // Loop columns and set renderable property according to settings
+ var initialColumnsVisible = self.options.initialColumnsVisible;
+
+ if (initialColumnsVisible) {
+ self.columns.each(function (col, index) {
+ col.set("renderable", (col.get("alwaysVisible")) ? true : index < initialColumnsVisible);
+ });
+ }
+ };
+
+ /**
+ * Loops over all columns and adds the columnManager instance to VisibilityHeaderCell columns.
+ *
+ * @method addManagerToColumns
+ */
+ Backgrid.Extension.ColumnManager.prototype.addManagerToColumns = function () {
+ var self = this;
+
+ self.columns.each(function (col) {
+ // Look for header cell
+ if (col.get("headerCell") === Backgrid.Extension.ColumnManager.ColumnVisibilityHeaderCell) {
+ col.set("headerCell", col.get("headerCell").extend({
+ columnManager: self
+ }));
+ }
+
+ if (col.get("headerCell") instanceof Backgrid.Extension.ColumnManager.ColumnVisibilityHeaderCell) {
+ col.get("headerCell").columnManager = self;
+ }
+ });
+ };
+
+ /**
+ * Convenience function to retrieve a column either directly or by its id.
+ * Returns false if no column is found.
+ *
+ * @method getColumn
+ * @param {string|number|Backgrid.Column} col
+ * @return {Backgrid.Column|boolean}
+ */
+ Backgrid.Extension.ColumnManager.prototype.getColumn = function (col) {
+ // If column is a string or number, try to find a column which has that ID
+ if (_.isNumber(col) || _.isString(col)) {
+ col = this.columns.get(col);
+ }
+ return (col instanceof Backgrid.Column) ? col : false;
+ };
+
+ /**
+ * Hides a column
+ *
+ * @method hidecolumn
+ * @param {string|number|Backgrid.Column} col
+ */
+ Backgrid.Extension.ColumnManager.prototype.hideColumn = function (col) {
+ // If column is a valid backgrid column, set the renderable property to false
+ var column = this.getColumn(col);
+ if (column) {
+ column.set("renderable", false);
+ }
+ };
+
+ /**
+ * Shows a column
+ *
+ * @method showColumn
+ * @param {string|number|Backgrid.Column} col
+ */
+ Backgrid.Extension.ColumnManager.prototype.showColumn = function (col) {
+ // If column is a valid backgrid column, set the renderable property to true
+ var column = this.getColumn(col);
+ if (column) {
+ column.set("renderable", true);
+ }
+ };
+
+ /**
+ * Toggles a columns' visibility
+ *
+ * @method toggleColumnVisibility
+ * @param {string|number|Backgrid.Column} col
+ */
+ Backgrid.Extension.ColumnManager.prototype.toggleColumnVisibility = function (col) {
+ // If column is a valid backgrid column, set the renderable property to true
+ var column = this.getColumn(col);
+ if (column) {
+ if (column.get("renderable")) {
+ this.hideColumn(column);
+ }
+ else {
+ this.showColumn(column);
+ }
+ }
+ };
+
+ /**
+ * Returns the managed column collection
+ *
+ * @method getColumnCollection
+ * @return {Backgrid.Columns}
+ */
+ Backgrid.Extension.ColumnManager.prototype.getColumnCollection = function () {
+ return this.columns;
+ };
+
+ /**
+ *
+ * @method setState
+ * @param {Array} state
+ * @param {boolean} applyState
+ * @return {boolean}
+ */
+ Backgrid.Extension.ColumnManager.prototype.setState = function (state, applyState) {
+ var self = this;
+
+ // Filter state
+ _.filter(state, function(columnState) {
+ if (!_.has(columnState, "name")) {
+ return false;
+ }
+
+ var column = self.columns.findWhere({
+ name: state.name
+ });
+
+ return typeof column !== "undefined";
+ });
+
+ // Check if state is valid
+ if (self.checkStateValidity(state) && state !== self.state) {
+ // Apply and save state
+ self.state = state;
+ self.trigger("state-changed", state);
+
+ if (applyState) {
+ return self.applyStateToColumns();
+ }
+ else {
+ return self.saveState();
+ }
+ }
+ return false;
+ };
+
+ /**
+ * @method getState
+ * @return {Array}
+ */
+ Backgrid.Extension.ColumnManager.prototype.getState = function () {
+ return this.state;
+ };
+
+ /**
+ *
+ * @method checkStateValidity
+ * @return {boolean}
+ */
+ Backgrid.Extension.ColumnManager.prototype.checkStateValidity = function (state) {
+ // Has to be array
+ if (!_.isArray(state) && _.isEmpty(state)) {
+ return false;
+ }
+
+ function checkValidityColumnState() {
+ return _.every(state, function(column) {
+ var valid = true;
+
+ // We require a name key
+ if (!_.has(column, "name")) {
+ valid = false;
+ }
+
+ // If renderable is set, should be boolean
+ if (_.has(column, "renderable")) {
+ if (!_.isBoolean(column.renderable)) {
+ valid = false;
+ }
+ }
+
+ // If displayOrder is set, should be a number
+ if (_.has(column, "displayOrder")) {
+ if (!_.isNumber(column.displayOrder)) {
+ valid = false;
+ }
+ }
+
+ // If width is set, should be a number or a string
+ if (_.has(column, "width")) {
+ if (!_.isNumber(column.width) && !_.isString(column.width)) {
+ valid = false;
+ }
+ }
+
+ return valid;
+ });
+ }
+
+ // Check if state is valid
+ if (this.options.stateChecking === "loose") {
+ // At least we require 'name' keys in every objec
+ return checkValidityColumnState();
+ }
+ else {
+ // Strict check
+ // Requires same length and valid name keys.
+ if (state.length !== this.columns.length && !checkValidityColumnState()) {
+ return false;
+ }
+
+ var columnNameKeys = this.columns.map(function (column) {
+ return column.get("name");
+ });
+
+ var newStateNameKeys = _.map(state, function (column) {
+ return column.name;
+ });
+
+ return columnNameKeys.sort().toString() === newStateNameKeys.sort().toString();
+ }
+ };
+
+
+ /**
+ *
+ * @method loadState
+ * @return {boolean}
+ */
+ Backgrid.Extension.ColumnManager.prototype.loadState = function () {
+ // Get state from storage
+ var state = JSON.parse(this.getStorage().getItem(this.getStorageKey()));
+ if (this.checkStateValidity(state)) {
+ return state;
+ }
+ return false;
+ };
+
+ /**
+ *
+ * @method saveState
+ * @param {boolean} [force] Override save settings.
+ * @return {boolean}
+ */
+ Backgrid.Extension.ColumnManager.prototype.saveState = function (force) {
+ if (this.options.saveState || force) {
+ this.getStorage().setItem(this.getStorageKey(), JSON.stringify(this.state));
+ this.trigger("state-saved");
+ return true;
+ }
+ return false;
+ };
+
+ /**
+ * @method getStorage
+ * @return {boolean|Storage}
+ * @private
+ */
+ Backgrid.Extension.ColumnManager.prototype.getStorage = function () {
+ // Check if storage functionality is available
+ if (typeof Storage !== "undefined") {
+ return (this.options.saveStateLocation === "sessionStorage") ? sessionStorage : localStorage;
+ }
+ else {
+ console.error("ColMrg: No storage support detected. State won't be saved.");
+ return false;
+ }
+ };
+
+ /**
+ * @method getStorageKey
+ * @return {string}
+ * @private
+ */
+ Backgrid.Extension.ColumnManager.prototype.getStorageKey = function () {
+ return (this.options.saveStateKey) ? "backgrid-colmgr-" + this.options.saveStateKey : "backgrid-colmgr";
+ };
+
+ /**
+ * @method stateUpdateHandler
+ * @return {boolean}
+ * @private
+ */
+ Backgrid.Extension.ColumnManager.prototype.stateUpdateHandler = function () {
+ var state = this.getStateFromColumns();
+ return this.setState(state);
+ };
+
+ /**
+ * @method getStateFromColumn
+ * @return {Array}
+ */
+ Backgrid.Extension.ColumnManager.prototype.getStateFromColumns = function() {
+ var self = this;
+
+ // Map state from columns
+ return this.columns.map(function(column) {
+ var columnState = {
+ name: column.get("name")
+ };
+
+ if (self.options.trackVisibility) {
+ columnState.renderable = column.get("renderable");
+ }
+ if (self.options.trackOrder) {
+ columnState.displayOrder = column.get("displayOrder");
+ }
+ if (self.options.trackSize) {
+ columnState.width = column.get("width");
+ }
+ return columnState;
+ });
+ };
+
+ /**
+ * @method applyStateToColumns
+ * @private
+ */
+ Backgrid.Extension.ColumnManager.prototype.applyStateToColumns = function () {
+ var self = this;
+
+ // Loop state
+ var ordered = false;
+ _.each(this.state, function(columnState) {
+ // Find column
+ var column = self.columns.findWhere({
+ name: columnState.name
+ });
+
+ if (_.has(columnState, "renderable")) {
+ column.set("renderable", columnState.renderable);
+ }
+ if (_.has(columnState, "width")) {
+ var oldWidth = column.get("width");
+ column.set("width", columnState.width, {silent: true});
+ if (oldWidth !== columnState.width) {
+ column.trigger("resize", column, columnState.width, oldWidth);
+ }
+ }
+
+ if (_.has(columnState, "displayOrder")) {
+ if (columnState.displayOrder !== column.get("displayOrder")) {
+ ordered = true;
+ }
+ column.set("displayOrder", columnState.displayOrder, {silent: true});
+ }
+ });
+
+ if (ordered) {
+ self.columns.sort();
+ self.columns.trigger("ordered");
+ }
+ };
+
+ //////////////////////////////////////////////
+ /////////////// UI Controls //////////////////
+ //////////////////////////////////////////////
+
+ /**
+ * A dropdown item view
+ *
+ * @class DropDownItemView
+ * @extends Backbone.View
+ */
+ var DropDownItemView = Backbone.View.extend({
+ className: "columnmanager-dropdown-item",
+ tagName: "li",
+
+ /**
+ * @method initialize
+ * @param {object} opts
+ * @param {Backgrid.Extension.ColumnManager} opts.columnManager ColumnManager instance.
+ * @param {Backgrid.Column} opts.column A backgrid column.
+ */
+ initialize: function (opts) {
+ this.columnManager = opts.columnManager;
+ this.column = opts.column;
+ this.template = opts.template;
+
+ _.bindAll(this, "render", "toggleVisibility");
+ this.column.on("change:renderable", this.render, this);
+ this.el.addEventListener("click", this.toggleVisibility, true);
+ },
+
+ /**
+ * @method render
+ * @return {DropDownItemView}
+ */
+ render: function () {
+ this.$el.empty();
+
+ this.$el.append(this.template({
+ label: this.column.get("label")
+ }));
+
+ if (this.column.get("renderable")) {
+ this.$el.addClass((this.column.get("renderable")) ? "visible" : null);
+ }
+ else {
+ this.$el.removeClass("visible");
+ }
+
+ return this;
+ },
+
+ /**
+ * Toggles visibility of column.
+ *
+ * @method toggleVisibility
+ * @param {object} e
+ */
+ toggleVisibility: function (e) {
+ if (e) {
+ this.stopPropagation(e);
+ }
+ this.columnManager.toggleColumnVisibility(this.column);
+ },
+
+ /**
+ * Convenience function to stop event propagation.
+ *
+ * @method stopPropagation
+ * @param {object} e
+ * @private
+ */
+ stopPropagation: function (e) {
+ e.stopPropagation();
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ }
+ });
+
+
+ /**
+ * Dropdown view container.
+ *
+ * @class DropDownView
+ * @extends Backbone.view
+ */
+ var DropDownView = Backbone.View.extend({
+ /**
+ * @property className
+ * @type String
+ * @default "columnmanager-dropdown-container"
+ */
+ className: "columnmanager-dropdown-container",
+
+ /**
+ * @method initialize
+ * @param {object} opts
+ * @param {Backgrid.Extension.ColumnManager} opts.columnManager ColumnManager instance.
+ * @param {Backbone.View} opts.DropdownItemView View to be used for the items.
+ * @param {Function} opts.dropdownItemTemplate
+ */
+ initialize: function (opts) {
+ this.options = opts;
+ this.columnManager = opts.columnManager;
+ this.ItemView = (opts.DropdownItemView instanceof Backbone.View) ? opts.DropdownItemView : DropDownItemView;
+ this.$dropdownButton = opts.$dropdownButton;
+
+ this.on("dropdown:opened", this.open, this);
+ this.on("dropdown:closed", this.close, this);
+ this.columnManager.columns.on("add remove", this.render, this);
+ },
+
+ /**
+ * @method render
+ * @return {DropDownView}
+ */
+ render: function () {
+ var view = this;
+ view.$el.empty();
+
+ // List all columns
+ this.columnManager.columns.each(function (col) {
+ if (!col.get("alwaysVisible")) {
+ view.$el.append(new view.ItemView({
+ column: col,
+ columnManager: view.columnManager,
+ template: view.options.dropdownItemTemplate
+ }).render().el);
+ }
+ });
+
+ return this;
+ },
+
+ /**
+ * Opens the dropdown.
+ *
+ * @method open
+ */
+ open: function () {
+ this.$el.addClass("open");
+
+ // Get button
+ var $button = this.$dropdownButton;
+
+ // Align
+ var align;
+ if (this.options.align === "auto") {
+ // Determine what alignment fits
+ var viewPortWidth = document.body.clientWidth || document.body.clientWidth;
+ align = (($button.offset().left + this.$el.outerWidth()) > viewPortWidth) ? "left" : "right";
+ }
+ else {
+ align = (this.options.align === "left" || this.options.align === "right") ?
+ (this.options.align === "right" ? "right" : "left") : "right";
+ }
+
+ var offset;
+ if (align === "left") {
+ // Align right by default
+ offset = $button.offset().left + $button.outerWidth() - this.$el.outerWidth();
+ this.$el.css("left", offset + "px");
+ }
+ else {
+ offset = $button.offset().left;
+ this.$el.css("left", offset + "px");
+ }
+
+ // Height position
+ var offsetHeight = $button.offset().top + $button.outerHeight();
+ this.$el.css("top", offsetHeight + "px");
+ },
+
+ /**
+ * Closes the dropdown.
+ *
+ * @method close
+ */
+ close: function () {
+ this.$el.removeClass("open");
+ }
+ });
+
+ /**
+ * UI control which manages visibility of columns.
+ * Inspired by: https://github.com/kjantzer/backbonejs-dropdown-view.
+ *
+ * @class Backgrid.Extension.ColumnManagerVisibilityControl
+ * @extends Backbone.View
+ */
+ Backgrid.Extension.ColumnManagerVisibilityControl = Backbone.View.extend({
+ /**
+ * @property tagName
+ * @type String
+ * @default "div"
+ */
+ tagName: "div",
+
+ /**
+ * @property className
+ * @type String
+ * @default "columnmanager-visibilitycontrol"
+ */
+ className: "columnmanager-visibilitycontrol",
+
+ /**
+ * @property defaultEvents
+ * @type Object
+ */
+ defaultEvents: {
+ "click": "stopPropagation"
+ },
+
+ /**
+ * @property defaultOpts
+ * @type Object
+ */
+ defaultOpts: {
+ width: null,
+ closeOnEsc: true,
+ closeOnClick: true,
+ openOnInit: false,
+ columnManager: null,
+
+ // Button
+ buttonTemplate: _.template("<button class='dropdown-button'>...</button>"),
+
+ // Container
+ DropdownView: DropDownView,
+ dropdownAlign: "auto",
+
+ // Item view
+ DropdownItemView: DropDownItemView,
+ dropdownItemTemplate: _.template("<span class='indicator'></span><span class='column-label'><%= label %></span>")
+ },
+
+ /**
+ * @method initialize
+ * @param {Object} opts
+ * @param {Backgrid.Extension.ColumnManager} opts.columnManager ColumnManager instance
+ */
+ initialize: function (opts) {
+ this.options = _.extend({}, this.defaultOpts, opts);
+ this.events = _.extend({}, this.defaultEvents, this.events || {});
+ this.columnManager = opts.columnManager;
+
+ // Option checking
+ if (!this.columnManager instanceof Backgrid.Extension.ColumnManager) {
+ console.error("Backgrid.ColumnManager: options.columns is not an instance of Backgrid.Columns");
+ }
+
+ // Bind scope to events
+ _.bindAll(this, "deferClose", "stopDeferClose", "closeOnEsc", "toggle", "render");
+
+ // UI events
+ document.body.addEventListener("click", this.deferClose, true);
+ this.el.addEventListener("click", this.stopDeferClose, true);
+ if (this.options.closeOnEsc) {
+ document.body.addEventListener("keyup", this.closeOnEsc, false);
+ }
+ this.el.addEventListener("click", this.toggle, false);
+
+ // Create elements
+ this.setup();
+
+ // Listen for dropdown view events indicating to open and/or close
+ this.view.on("dropdown:close", this.close, this);
+ this.view.on("dropdown:open", this.open, this);
+ },
+
+ /**
+ * @method delayStart
+ * @private
+ */
+ delayStart: function () {
+ clearTimeout(this.closeTimeout);
+ this.delayTimeout = setTimeout(this.open.bind(this), this.options.delay);
+ },
+
+ /**
+ * @method delayEnd
+ * @private
+ */
+ delayEnd: function () {
+ clearTimeout(this.delayTimeout);
+ this.closeTimeout = setTimeout(this.close.bind(this), 300);
+ },
+
+ /**
+ * @method setup
+ * @private
+ */
+ setup: function () {
+ // Override element width
+ if (this.options.width) {
+ this.$el.width(this.options.width + "px");
+ }
+
+ // Create button element
+ this.$dropdownButton = $(this.options.buttonTemplate());
+
+ var viewOptions = {
+ columnManager: this.columnManager,
+ DropdownItemView: this.options.DropdownItemView,
+ dropdownItemTemplate: this.options.dropdownItemTemplate,
+ align: this.options.dropdownAlign,
+ $dropdownButton: this.$dropdownButton
+ };
+
+ // Check if a different childView has been provided, if not, use default dropdown view
+ this.view = (this.options.DropdownView instanceof Backbone.View) ?
+ new this.options.DropdownView(viewOptions) :
+ new DropDownView(viewOptions);
+ },
+
+ /**
+ * @method setup
+ */
+ render: function () {
+ this.$el.empty();
+
+ // Render button
+ this.$el.append(this.$dropdownButton);
+
+ // Render inner view
+ this.view.render(); // tell the inner view to render itself
+ $(document.body).append(this.view.el);
+ return this;
+ },
+
+ /**
+ * Convenience function to stop event propagation
+ *
+ * @method stopPropagation
+ * @param {object} e
+ * @private
+ */
+ stopPropagation: function (e) {
+ e.stopPropagation();
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ },
+
+ /**
+ * Toggle the dropdown visibility
+ *
+ * @method toggle
+ * @param {object} [e]
+ */
+ toggle: function (e) {
+ if (this.isOpen !== true) {
+ this.open(e);
+ }
+ else {
+ this.close(e);
+ }
+ },
+
+ /**
+ * Open the dropdown
+ *
+ * @method open
+ * @param {object} [e]
+ */
+ open: function (e) {
+ clearTimeout(this.closeTimeout);
+ clearTimeout(this.deferCloseTimeout);
+
+ if (e) {
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ }
+ if (e.preventDefault) {
+ e.preventDefault();
+ }
+ e.cancelBubble = true;
+ }
+
+ // Don't do anything if already open
+ if (this.isOpen) {
+ return;
+ }
+
+ this.isOpen = true;
+ this.$el.addClass("open");
+ this.trigger("dropdown:opened");
+
+ // Notify child view
+ this.view.trigger("dropdown:opened");
+ },
+
+ /**
+ * Close the dropdown
+ *
+ * @method close
+ * @param {object} [e]
+ */
+ close: function (e) {
+ // Don't do anything if already closed
+ if (!this.isOpen) {
+ return;
+ }
+
+ this.isOpen = false;
+ this.$el.removeClass("open");
+ this.trigger("dropdown:closed");
+
+ // Notify child view
+ this.view.trigger("dropdown:closed");
+ },
+
+ /**
+ * Close the dropdown on esc
+ *
+ * @method closeOnEsc
+ * @param {object} e
+ * @private
+ */
+ closeOnEsc: function (e) {
+ if (e.which === 27) {
+ this.deferClose();
+ }
+ },
+
+ /**
+ * @method deferClose
+ * @private
+ */
+ deferClose: function () {
+ this.deferCloseTimeout = setTimeout(this.close.bind(this), 0);
+ },
+
+ /**
+ * @method stopDeferClose
+ * @private
+ */
+ stopDeferClose: function (e) {
+ clearTimeout(this.deferCloseTimeout);
+ },
+
+ /**
+ * Clean up this control
+ *
+ * @method remove
+ * @chainable
+ */
+ remove: function () {
+ // Remove event listeners
+ document.body.removeEventListener("click", this.deferClose);
+ this.el.removeEventListener("click", this.stopDeferClose);
+ if (this.options.closeOnEsc) {
+ document.body.removeEventListener("keyup", this.closeOnEsc);
+ }
+ this.el.removeEventListener("click", this.toggle);
+
+ // Remove DOM element
+ $(this.view.el).remove();
+
+ // Invoke original backbone methods
+ return Backbone.View.prototype.remove.apply(this, arguments);
+ }
+ });
+
+ /**
+ * Backgrid HeaderCell containing ColumnManagerVisibilityControl
+ *
+ * @class Backgrid.Extension.ColumnVisibilityHeaderCell
+ * @extends Backgrid.HeaderCell
+ */
+
+ Backgrid.Extension.ColumnManager.ColumnVisibilityHeaderCell = Backgrid.HeaderCell.extend({
+ initialize: function (options) {
+ Backgrid.HeaderCell.prototype.initialize.apply(this, arguments);
+
+ // Add class
+ this.$el.addClass(this.column.get("name"));
+ },
+ render: function () {
+ this.$el.empty();
+
+ // Add control
+ var colVisibilityControl = this.colVisibilityControl = new Backgrid.Extension.ColumnManagerVisibilityControl({
+ columnManager: this.columnManager
+ });
+
+ // Add to header
+ this.$el.html(colVisibilityControl.render().el);
+
+ this.delegateEvents();
+ return this;
+ },
+
+ /**
+ * Clean up this cell.
+ *
+ * @method remove
+ * @chainable
+ */
+ remove: function () {
+ // Remove UI control
+ this.colVisibilityControl.remove();
+
+ // Invoke super
+ /*eslint no-underscore-dangle:0*/
+ return Backgrid.HeaderCell.__super__.remove.apply(this, arguments);
+ }
+ });
+
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+ module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+ module.exports = __WEBPACK_EXTERNAL_MODULE_2__;
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+ module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+ module.exports = __WEBPACK_EXTERNAL_MODULE_4__;
+
+/***/ }
+/******/ ])
+});
+;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.min.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.min.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.min.js
new file mode 100644
index 0000000..3312282
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-columnmanager/Backgrid.ColumnManager.min.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("Backbone"),require("Backgrid"),require("_"),require("jQuery")):"function"==typeof define&&define.amd?define(["Backbone","Backgrid","_","jQuery"],t):"object"==typeof exports?exports["Backgrid.Extension.ColumnManager"]=t(require("Backbone"),require("Backgrid"),require("_"),require("jQuery")):e["Backgrid.Extension.ColumnManager"]=t(e.Backbone,e.Backgrid,e._,e.jQuery)}(this,function(e,t,n,i){return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={exports:{},id:i,loaded:!1};return e[i].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";var i=n(3),o=n(4),s=n(1),r=n(2);r.Extension.ColumnManager=function(e,t,n){i.extend(this,s.Events);var o={initialColumnsVisible:null,trackSize:!0,trackOrder:!0,trackVisibility:!0,stateChecking:"strict",saveState:!1,saveStateKey:"",saveStateLocation:"localStorage",loadStateOnInit:!
1};if(this.options=i.extend({},o,t),this.state=[],e instanceof r.Columns){this.columns=e,e.columnManager=this,this.addManagerToColumns();var a=this.options.loadStateOnInit?this.loadState():!1;if(n&&this.checkStateValidity(n)?this.setState(n,!0):a?this.setState(a,!0):(this.setInitialColumnVisibility(),this.setState(this.getStateFromColumns())),this.options.trackVisibility||this.options.trackSize||this.options.trackOrder){var l=""+(this.options.trackVisibility?"change:renderable ":"")+(this.options.trackSize?"resize ":"")+(this.options.trackOrder?"ordered":"");this.columns.on(l,i.bind(this.stateUpdateHandler,this))}}else console.error("Backgrid.ColumnManager: options.columns is not an instance of Backgrid.Columns")},r.Extension.ColumnManager.prototype.setInitialColumnVisibility=function(){var e=this,t=e.options.initialColumnsVisible;t&&e.columns.each(function(e,n){e.set("renderable",e.get("alwaysVisible")?!0:t>n)})},r.Extension.ColumnManager.prototype.addManagerToColumns=function(){va
r e=this;e.columns.each(function(t){t.get("headerCell")===r.Extension.ColumnManager.ColumnVisibilityHeaderCell&&t.set("headerCell",t.get("headerCell").extend({columnManager:e})),t.get("headerCell")instanceof r.Extension.ColumnManager.ColumnVisibilityHeaderCell&&(t.get("headerCell").columnManager=e)})},r.Extension.ColumnManager.prototype.getColumn=function(e){return(i.isNumber(e)||i.isString(e))&&(e=this.columns.get(e)),e instanceof r.Column?e:!1},r.Extension.ColumnManager.prototype.hideColumn=function(e){var t=this.getColumn(e);t&&t.set("renderable",!1)},r.Extension.ColumnManager.prototype.showColumn=function(e){var t=this.getColumn(e);t&&t.set("renderable",!0)},r.Extension.ColumnManager.prototype.toggleColumnVisibility=function(e){var t=this.getColumn(e);t&&(t.get("renderable")?this.hideColumn(t):this.showColumn(t))},r.Extension.ColumnManager.prototype.getColumnCollection=function(){return this.columns},r.Extension.ColumnManager.prototype.setState=function(e,t){var n=this;return i.
filter(e,function(t){if(!i.has(t,"name"))return!1;var o=n.columns.findWhere({name:e.name});return"undefined"!=typeof o}),n.checkStateValidity(e)&&e!==n.state?(n.state=e,n.trigger("state-changed",e),t?n.applyStateToColumns():n.saveState()):!1},r.Extension.ColumnManager.prototype.getState=function(){return this.state},r.Extension.ColumnManager.prototype.checkStateValidity=function(e){function t(){return i.every(e,function(e){var t=!0;return i.has(e,"name")||(t=!1),i.has(e,"renderable")&&(i.isBoolean(e.renderable)||(t=!1)),i.has(e,"displayOrder")&&(i.isNumber(e.displayOrder)||(t=!1)),i.has(e,"width")&&(i.isNumber(e.width)||i.isString(e.width)||(t=!1)),t})}if(!i.isArray(e)&&i.isEmpty(e))return!1;if("loose"===this.options.stateChecking)return t();if(e.length!==this.columns.length&&!t())return!1;var n=this.columns.map(function(e){return e.get("name")}),o=i.map(e,function(e){return e.name});return n.sort().toString()===o.sort().toString()},r.Extension.ColumnManager.prototype.loadState=func
tion(){var e=JSON.parse(this.getStorage().getItem(this.getStorageKey()));return this.checkStateValidity(e)?e:!1},r.Extension.ColumnManager.prototype.saveState=function(e){return this.options.saveState||e?(this.getStorage().setItem(this.getStorageKey(),JSON.stringify(this.state)),this.trigger("state-saved"),!0):!1},r.Extension.ColumnManager.prototype.getStorage=function(){return"undefined"!=typeof Storage?"sessionStorage"===this.options.saveStateLocation?sessionStorage:localStorage:(console.error("ColMrg: No storage support detected. State won't be saved."),!1)},r.Extension.ColumnManager.prototype.getStorageKey=function(){return this.options.saveStateKey?"backgrid-colmgr-"+this.options.saveStateKey:"backgrid-colmgr"},r.Extension.ColumnManager.prototype.stateUpdateHandler=function(){var e=this.getStateFromColumns();return this.setState(e)},r.Extension.ColumnManager.prototype.getStateFromColumns=function(){var e=this;return this.columns.map(function(t){var n={name:t.get("name")};return
e.options.trackVisibility&&(n.renderable=t.get("renderable")),e.options.trackOrder&&(n.displayOrder=t.get("displayOrder")),e.options.trackSize&&(n.width=t.get("width")),n})},r.Extension.ColumnManager.prototype.applyStateToColumns=function(){var e=this,t=!1;i.each(this.state,function(n){var o=e.columns.findWhere({name:n.name});if(i.has(n,"renderable")&&o.set("renderable",n.renderable),i.has(n,"width")){var s=o.get("width");o.set("width",n.width,{silent:!0}),s!==n.width&&o.trigger("resize",o,n.width,s)}i.has(n,"displayOrder")&&(n.displayOrder!==o.get("displayOrder")&&(t=!0),o.set("displayOrder",n.displayOrder,{silent:!0}))}),t&&(e.columns.sort(),e.columns.trigger("ordered"))};var a=s.View.extend({className:"columnmanager-dropdown-item",tagName:"li",initialize:function(e){this.columnManager=e.columnManager,this.column=e.column,this.template=e.template,i.bindAll(this,"render","toggleVisibility"),this.column.on("change:renderable",this.render,this),this.el.addEventListener("click",this.
toggleVisibility,!0)},render:function(){return this.$el.empty(),this.$el.append(this.template({label:this.column.get("label")})),this.column.get("renderable")?this.$el.addClass(this.column.get("renderable")?"visible":null):this.$el.removeClass("visible"),this},toggleVisibility:function(e){e&&this.stopPropagation(e),this.columnManager.toggleColumnVisibility(this.column)},stopPropagation:function(e){e.stopPropagation(),e.stopImmediatePropagation(),e.preventDefault()}}),l=s.View.extend({className:"columnmanager-dropdown-container",initialize:function(e){this.options=e,this.columnManager=e.columnManager,this.ItemView=e.DropdownItemView instanceof s.View?e.DropdownItemView:a,this.$dropdownButton=e.$dropdownButton,this.on("dropdown:opened",this.open,this),this.on("dropdown:closed",this.close,this),this.columnManager.columns.on("add remove",this.render,this)},render:function(){var e=this;return e.$el.empty(),this.columnManager.columns.each(function(t){t.get("alwaysVisible")||e.$el.append(n
ew e.ItemView({column:t,columnManager:e.columnManager,template:e.options.dropdownItemTemplate}).render().el)}),this},open:function(){this.$el.addClass("open");var e,t=this.$dropdownButton;if("auto"===this.options.align){var n=document.body.clientWidth||document.body.clientWidth;e=t.offset().left+this.$el.outerWidth()>n?"left":"right"}else e="left"===this.options.align||"right"===this.options.align?"right"===this.options.align?"right":"left":"right";var i;"left"===e?(i=t.offset().left+t.outerWidth()-this.$el.outerWidth(),this.$el.css("left",i+"px")):(i=t.offset().left,this.$el.css("left",i+"px"));var o=t.offset().top+t.outerHeight();this.$el.css("top",o+"px")},close:function(){this.$el.removeClass("open")}});r.Extension.ColumnManagerVisibilityControl=s.View.extend({tagName:"div",className:"columnmanager-visibilitycontrol",defaultEvents:{click:"stopPropagation"},defaultOpts:{width:null,closeOnEsc:!0,closeOnClick:!0,openOnInit:!1,columnManager:null,buttonTemplate:i.template("<button cl
ass='dropdown-button'>...</button>"),DropdownView:l,dropdownAlign:"auto",DropdownItemView:a,dropdownItemTemplate:i.template("<span class='indicator'></span><span class='column-label'><%= label %></span>")},initialize:function(e){this.options=i.extend({},this.defaultOpts,e),this.events=i.extend({},this.defaultEvents,this.events||{}),this.columnManager=e.columnManager,!this.columnManager instanceof r.Extension.ColumnManager&&console.error("Backgrid.ColumnManager: options.columns is not an instance of Backgrid.Columns"),i.bindAll(this,"deferClose","stopDeferClose","closeOnEsc","toggle","render"),document.body.addEventListener("click",this.deferClose,!0),this.el.addEventListener("click",this.stopDeferClose,!0),this.options.closeOnEsc&&document.body.addEventListener("keyup",this.closeOnEsc,!1),this.el.addEventListener("click",this.toggle,!1),this.setup(),this.view.on("dropdown:close",this.close,this),this.view.on("dropdown:open",this.open,this)},delayStart:function(){clearTimeout(this.cl
oseTimeout),this.delayTimeout=setTimeout(this.open.bind(this),this.options.delay)},delayEnd:function(){clearTimeout(this.delayTimeout),this.closeTimeout=setTimeout(this.close.bind(this),300)},setup:function(){this.options.width&&this.$el.width(this.options.width+"px"),this.$dropdownButton=o(this.options.buttonTemplate());var e={columnManager:this.columnManager,DropdownItemView:this.options.DropdownItemView,dropdownItemTemplate:this.options.dropdownItemTemplate,align:this.options.dropdownAlign,$dropdownButton:this.$dropdownButton};this.view=this.options.DropdownView instanceof s.View?new this.options.DropdownView(e):new l(e)},render:function(){return this.$el.empty(),this.$el.append(this.$dropdownButton),this.view.render(),o(document.body).append(this.view.el),this},stopPropagation:function(e){e.stopPropagation(),e.stopImmediatePropagation(),e.preventDefault()},toggle:function(e){this.isOpen!==!0?this.open(e):this.close(e)},open:function(e){clearTimeout(this.closeTimeout),clearTimeou
t(this.deferCloseTimeout),e&&(e.stopPropagation&&e.stopPropagation(),e.preventDefault&&e.preventDefault(),e.cancelBubble=!0),this.isOpen||(this.isOpen=!0,this.$el.addClass("open"),this.trigger("dropdown:opened"),this.view.trigger("dropdown:opened"))},close:function(e){this.isOpen&&(this.isOpen=!1,this.$el.removeClass("open"),this.trigger("dropdown:closed"),this.view.trigger("dropdown:closed"))},closeOnEsc:function(e){27===e.which&&this.deferClose()},deferClose:function(){this.deferCloseTimeout=setTimeout(this.close.bind(this),0)},stopDeferClose:function(e){clearTimeout(this.deferCloseTimeout)},remove:function(){return document.body.removeEventListener("click",this.deferClose),this.el.removeEventListener("click",this.stopDeferClose),this.options.closeOnEsc&&document.body.removeEventListener("keyup",this.closeOnEsc),this.el.removeEventListener("click",this.toggle),o(this.view.el).remove(),s.View.prototype.remove.apply(this,arguments)}}),r.Extension.ColumnManager.ColumnVisibilityHeader
Cell=r.HeaderCell.extend({initialize:function(e){r.HeaderCell.prototype.initialize.apply(this,arguments),this.$el.addClass(this.column.get("name"))},render:function(){this.$el.empty();var e=this.colVisibilityControl=new r.Extension.ColumnManagerVisibilityControl({columnManager:this.columnManager});return this.$el.html(e.render().el),this.delegateEvents(),this},remove:function(){return this.colVisibilityControl.remove(),r.HeaderCell.__super__.remove.apply(this,arguments)}})},function(t,n,i){t.exports=e},function(e,n,i){e.exports=t},function(e,t,i){e.exports=n},function(e,t,n){e.exports=i}])});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/css/backgrid-filter.css
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/css/backgrid-filter.css b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/css/backgrid-filter.css
new file mode 100644
index 0000000..4c689d0
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/css/backgrid-filter.css
@@ -0,0 +1,193 @@
+/*
+ backgrid-filter
+ http://github.com/wyuenho/backgrid
+
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+ Licensed under the MIT @license.
+*/
+
+/*
+ Search Icon CSS derived from:
+
+ PURE CSS GUI ICONS
+ by Nicolas Gallagher
+ - http://nicolasgallagher.com/pure-css-gui-icons/
+
+ http://nicolasgallagher.com
+ http://twitter.com/necolas
+
+ Created: 29 July 2010
+ Version: 1.0.1
+
+ Dual licensed under MIT and GNU GPLv2 (c) Nicolas Gallagher
+*/
+
+.backgrid-filter.form-search {
+ position: relative;
+ width: 248px;
+ height: 30px;
+ margin: 20px;
+}
+
+/*
+ Search Icon
+*/
+
+.backgrid-filter .search {
+ position: absolute;
+ top: 50%;
+ left: 6px;
+ z-index: 1000;
+ width: 10px;
+ height: 20px;
+ margin-top: -10px;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+.backgrid-filter .search:before {
+ position: absolute;
+ top: 50%;
+ left: 0;
+ width: 6px;
+ height: 6px;
+ margin-top: -6px;
+ background: transparent;
+ border: 3px solid gray;
+ -webkit-border-radius: 12px;
+ -moz-border-radius: 12px;
+ border-radius: 12px;
+ content: "";
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+.backgrid-filter .search:after {
+ position: absolute;
+ top: 50%;
+ left: 10px;
+ width: 3px;
+ height: 7px;
+ margin-top: 2px;
+ background-color: gray;
+ content: "";
+ -webkit-transform: rotate(-45deg);
+ -moz-transform: rotate(-45deg);
+ -ms-transform: rotate(-45deg);
+ -o-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+/*
+ Clear button
+ */
+
+.backgrid-filter .clear {
+ position: absolute;
+ top: 50%;
+ right: 8px;
+ z-index: 1000;
+ width: 10px;
+ height: 20px;
+ margin-top: -10px;
+ font-family: sans-serif;
+ font-size: 20px;
+ font-weight: bold;
+ line-height: 20px;
+ color: gray;
+ text-decoration: none;
+}
+
+.backgrid-filter input[type="search"] {
+ position: absolute;
+ display: inline-block;
+ width: 206px;
+ height: 20px;
+ padding: 4px 6px;
+ font-weight: normal;
+ color: #555;
+ vertical-align: middle;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -o-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+}
+
+/*
+ Normalize the search input box, with code borrowed from normalize.css.
+
+ https://github.com/necolas/normalize.css/
+
+ Copyright (c) Nicolas Gallagher and Jonathan Neal, MIT @license.
+ */
+
+/*
+ * 1. Correct font family not being inherited in all browsers.
+ * 2. Correct font size not being inherited in all browsers.
+ * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
+ * 4. Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet.
+ */
+
+.backgrid-filter input {
+ margin: 0;
+ font-family: inherit;
+ font-size: 100%;
+ line-height: normal;
+}
+
+/*
+ * Re-set default cursor for disabled elements.
+ */
+
+.backgrid-filter input[disabled] {
+ cursor: default;
+}
+
+/*
+ * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
+ * (include `-moz` to future-proof).
+ */
+
+.backgrid-filter input[type="search"] {
+ outline: none;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: none;
+}
+
+/*
+ * Remove the default clear button on IE
+ */
+
+.backgrid-filter input[type="search"]::-ms-clear {
+ display: none;
+}
+
+/*
+ * Remove inner padding and border in Firefox 4+.
+ */
+
+.backgrid-filter input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+.backgrid-filter input[type="search"] {
+ padding-right: 18px;
+ padding-left: 22px;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.js
new file mode 100644
index 0000000..66b1c21
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.js
@@ -0,0 +1,487 @@
+/*
+ backgrid-filter
+ http://github.com/wyuenho/backgrid
+
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+ Licensed under the MIT @license.
+*/
+(function (root, factory) {
+
+ // CommonJS
+ if (typeof exports == "object") {
+ (function () {
+ var lunr;
+ try { lunr = require("lunr"); } catch (e) {}
+ module.exports = factory(require("underscore"),
+ require("backbone"),
+ require("backgrid"),
+ lunr);
+ }());
+ }
+ // Browser
+ else {
+ factory(root._, root.Backbone, root.Backgrid, root.lunr);
+ }
+
+}(this, function (_, Backbone, Backgrid, lunr) {
+
+ "use strict";
+
+ /**
+ ServerSideFilter is a search form widget that submits a query to the server
+ for filtering the current collection.
+
+ @class Backgrid.Extension.ServerSideFilter
+ */
+ var ServerSideFilter = Backgrid.Extension.ServerSideFilter = Backbone.View.extend({
+
+ /** @property */
+ tagName: "form",
+
+ /** @property */
+ className: "backgrid-filter form-search",
+
+ /** @property {function(Object, ?Object=): string} template */
+ template: _.template('<span class="search"> </span><input type="search" <% if (placeholder) { %> placeholder="<%- placeholder %>" <% } %> name="<%- name %>" /><a class="clear" data-backgrid-action="clear" href="#">×</a>', null, {variable: null}),
+
+ /** @property */
+ events: {
+ "keyup input[type=search]": "showClearButtonMaybe",
+ "click a[data-backgrid-action=clear]": "clear",
+ "submit": "search"
+ },
+
+ /** @property {string} [name='q'] Query key */
+ name: "q",
+
+ /**
+ @property {string} [placeholder] The HTML5 placeholder to appear beneath
+ the search box.
+ */
+ placeholder: null,
+
+ /**
+ @param {Object} options
+ @param {Backbone.Collection} options.collection
+ @param {string} [options.name]
+ @param {string} [options.placeholder]
+ @param {function(Object): string} [options.template]
+ */
+ initialize: function (options) {
+ ServerSideFilter.__super__.initialize.apply(this, arguments);
+ this.name = options.name || this.name;
+ this.placeholder = options.placeholder || this.placeholder;
+ this.template = options.template || this.template;
+
+ // Persist the query on pagination
+ var collection = this.collection, self = this;
+ if (Backbone.PageableCollection &&
+ collection instanceof Backbone.PageableCollection &&
+ collection.mode == "server") {
+ collection.queryParams[this.name] = function () {
+ return self.searchBox().val() || null;
+ };
+ }
+ },
+
+ /**
+ Event handler. Show the clear button when the search box has text, hide
+ it otherwise.
+ */
+ showClearButtonMaybe: function () {
+ var $clearButton = this.clearButton();
+ var searchTerms = this.searchBox().val();
+ if (searchTerms) $clearButton.show();
+ else $clearButton.hide();
+ },
+
+ /**
+ Returns the search input box.
+ */
+ searchBox: function () {
+ return this.$el.find("input[type=search]");
+ },
+
+ /**
+ Returns the clear button.
+ */
+ clearButton: function () {
+ return this.$el.find("a[data-backgrid-action=clear]");
+ },
+
+ /**
+ Upon search form submission, this event handler constructs a query
+ parameter object and pass it to Collection#fetch for server-side
+ filtering.
+
+ If the collection is a PageableCollection, searching will go back to the
+ first page.
+ */
+ search: function (e) {
+ if (e) e.preventDefault();
+
+ var data = {};
+ var query = this.searchBox().val();
+ if (query) data[this.name] = query;
+
+ var collection = this.collection;
+
+ // go back to the first page on search
+ if (Backbone.PageableCollection &&
+ collection instanceof Backbone.PageableCollection) {
+ collection.getFirstPage({data: data, reset: true, fetch: true});
+ }
+ else collection.fetch({data: data, reset: true});
+ },
+
+ /**
+ Event handler for the clear button. Clears the search box and refetch the
+ collection.
+
+ If the collection is a PageableCollection, clearing will go back to the
+ first page.
+ */
+ clear: function (e) {
+ if (e) e.preventDefault();
+ this.searchBox().val(null);
+ this.showClearButtonMaybe();
+
+ var collection = this.collection;
+
+ // go back to the first page on clear
+ if (Backbone.PageableCollection &&
+ collection instanceof Backbone.PageableCollection) {
+ collection.getFirstPage({reset: true, fetch: true});
+ }
+ else collection.fetch({reset: true});
+ },
+
+ /**
+ Renders a search form with a text box, optionally with a placeholder and
+ a preset value if supplied during initialization.
+ */
+ render: function () {
+ this.$el.empty().append(this.template({
+ name: this.name,
+ placeholder: this.placeholder,
+ value: this.value
+ }));
+ this.showClearButtonMaybe();
+ this.delegateEvents();
+ return this;
+ }
+
+ });
+
+ /**
+ ClientSideFilter is a search form widget that searches a collection for
+ model matches against a query on the client side. The exact matching
+ algorithm can be overriden by subclasses.
+
+ @class Backgrid.Extension.ClientSideFilter
+ @extends Backgrid.Extension.ServerSideFilter
+ */
+ var ClientSideFilter = Backgrid.Extension.ClientSideFilter = ServerSideFilter.extend({
+
+ /** @property */
+ events: _.extend({}, ServerSideFilter.prototype.events, {
+ "click a[data-backgrid-action=clear]": function (e) {
+ e.preventDefault();
+ this.clear();
+ },
+ "keydown input[type=search]": "search",
+ "submit": function (e) {
+ e.preventDefault();
+ this.search();
+ }
+ }),
+
+ /**
+ @property {?Array.<string>} [fields] A list of model field names to
+ search for matches. If null, all of the fields will be searched.
+ */
+ fields: null,
+
+ /**
+ @property [wait=149] The time in milliseconds to wait since the last
+ change to the search box's value before searching. This value can be
+ adjusted depending on how often the search box is used and how large the
+ search index is.
+ */
+ wait: 149,
+
+ /**
+ Debounces the #search and #clear methods and makes a copy of the given
+ collection for searching.
+
+ @param {Object} options
+ @param {Backbone.Collection} options.collection
+ @param {string} [options.placeholder]
+ @param {string} [options.fields]
+ @param {string} [options.wait=149]
+ */
+ initialize: function (options) {
+ ClientSideFilter.__super__.initialize.apply(this, arguments);
+
+ this.fields = options.fields || this.fields;
+ this.wait = options.wait || this.wait;
+
+ this._debounceMethods(["search", "clear"]);
+
+ var collection = this.collection = this.collection.fullCollection || this.collection;
+ var shadowCollection = this.shadowCollection = collection.clone();
+
+ this.listenTo(collection, "add", function (model, collection, options) {
+ shadowCollection.add(model, options);
+ });
+ this.listenTo(collection, "remove", function (model, collection, options) {
+ shadowCollection.remove(model, options);
+ });
+ this.listenTo(collection, "sort", function (col) {
+ if (!this.searchBox().val()) shadowCollection.reset(col.models);
+ });
+ this.listenTo(collection, "reset", function (col, options) {
+ options = _.extend({reindex: true}, options || {});
+ if (options.reindex && options.from == null && options.to == null) {
+ shadowCollection.reset(col.models);
+ }
+ });
+ },
+
+ _debounceMethods: function (methodNames) {
+ if (_.isString(methodNames)) methodNames = [methodNames];
+
+ this.undelegateEvents();
+
+ for (var i = 0, l = methodNames.length; i < l; i++) {
+ var methodName = methodNames[i];
+ var method = this[methodName];
+ this[methodName] = _.debounce(method, this.wait);
+ }
+
+ this.delegateEvents();
+ },
+
+ /**
+ Constructs a Javascript regular expression object for #makeMatcher.
+
+ This default implementation takes a query string and returns a Javascript
+ RegExp object that matches any of the words contained in the query string
+ case-insensitively. Override this method to return a different regular
+ expression matcher if this behavior is not desired.
+
+ @param {string} query The search query in the search box.
+ @return {RegExp} A RegExp object to match against model #fields.
+ */
+ makeRegExp: function (query) {
+ return new RegExp(query.trim().split(/\s+/).join("|"), "i");
+ },
+
+ /**
+ This default implementation takes a query string and returns a matcher
+ function that looks for matches in the model's #fields or all of its
+ fields if #fields is null, for any of the words in the query
+ case-insensitively using the regular expression object returned from
+ #makeRegExp.
+
+ Most of time, you'd want to override the regular expression used for
+ matching. If so, please refer to the #makeRegExp documentation,
+ otherwise, you can override this method to return a custom matching
+ function.
+
+ Subclasses overriding this method must take care to conform to the
+ signature of the matcher function. The matcher function is a function
+ that takes a model as paramter and returns true if the model matches a
+ search, or false otherwise.
+
+ In addition, when the matcher function is called, its context will be
+ bound to this ClientSideFilter object so it has access to the filter's
+ attributes and methods.
+
+ @param {string} query The search query in the search box.
+ @return {function(Backbone.Model):boolean} A matching function.
+ */
+ makeMatcher: function (query) {
+ var regexp = this.makeRegExp(query);
+ return function (model) {
+ var keys = this.fields || model.keys();
+ for (var i = 0, l = keys.length; i < l; i++) {
+ if (regexp.test(model.get(keys[i]) + "")) return true;
+ }
+ return false;
+ };
+ },
+
+ /**
+ Takes the query from the search box, constructs a matcher with it and
+ loops through collection looking for matches. Reset the given collection
+ when all the matches have been found.
+
+ If the collection is a PageableCollection, searching will go back to the
+ first page.
+ */
+ search: function () {
+ var matcher = _.bind(this.makeMatcher(this.searchBox().val()), this);
+ var col = this.collection;
+ if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
+ col.reset(this.shadowCollection.filter(matcher), {reindex: false});
+ },
+
+ /**
+ Clears the search box and reset the collection to its original.
+
+ If the collection is a PageableCollection, clearing will go back to the
+ first page.
+ */
+ clear: function () {
+ this.searchBox().val(null);
+ this.showClearButtonMaybe();
+ var col = this.collection;
+ if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
+ col.reset(this.shadowCollection.models, {reindex: false});
+ }
+
+ });
+
+ /**
+ LunrFilter is a ClientSideFilter that uses [lunrjs](http://lunrjs.com/) to
+ index the text fields of each model for a collection, and performs
+ full-text searching.
+
+ @class Backgrid.Extension.LunrFilter
+ @extends Backgrid.Extension.ClientSideFilter
+ */
+ var LunrFilter = Backgrid.Extension.LunrFilter = ClientSideFilter.extend({
+
+ /**
+ @property {string} [ref="id"]`lunrjs` document reference attribute name.
+ */
+ ref: "id",
+
+ /**
+ @property {Object} fields A hash of `lunrjs` index field names and boost
+ value. Unlike ClientSideFilter#fields, LunrFilter#fields is _required_ to
+ initialize the index.
+ */
+ fields: null,
+
+ /**
+ Indexes the underlying collection on construction. The index will refresh
+ when the underlying collection is reset. If any model is added, removed
+ or if any indexed fields of any models has changed, the index will be
+ updated.
+
+ @param {Object} options
+ @param {Backbone.Collection} options.collection
+ @param {string} [options.placeholder]
+ @param {string} [options.ref] `lunrjs` document reference attribute name.
+ @param {Object} [options.fields] A hash of `lunrjs` index field names and
+ boost value.
+ @param {number} [options.wait]
+ */
+ initialize: function (options) {
+ LunrFilter.__super__.initialize.apply(this, arguments);
+
+ this.ref = options.ref || this.ref;
+
+ var collection = this.collection = this.collection.fullCollection || this.collection;
+ this.listenTo(collection, "add", this.addToIndex);
+ this.listenTo(collection, "remove", this.removeFromIndex);
+ this.listenTo(collection, "reset", this.resetIndex);
+ this.listenTo(collection, "change", this.updateIndex);
+
+ this.resetIndex(collection);
+ },
+
+ /**
+ Reindex the collection. If `options.reindex` is `false`, this method is a
+ no-op.
+
+ @param {Backbone.Collection} collection
+ @param {Object} [options]
+ @param {boolean} [options.reindex=true]
+ */
+ resetIndex: function (collection, options) {
+ options = _.extend({reindex: true}, options || {});
+
+ if (options.reindex) {
+ var self = this;
+ this.index = lunr(function () {
+ _.each(self.fields, function (boost, fieldName) {
+ this.field(fieldName, boost);
+ this.ref(self.ref);
+ }, this);
+ });
+
+ collection.each(function (model) {
+ this.addToIndex(model);
+ }, this);
+ }
+ },
+
+ /**
+ Adds the given model to the index.
+
+ @param {Backbone.Model} model
+ */
+ addToIndex: function (model) {
+ var index = this.index;
+ var doc = model.toJSON();
+ if (index.documentStore.has(doc[this.ref])) index.update(doc);
+ else index.add(doc);
+ },
+
+ /**
+ Removes the given model from the index.
+
+ @param {Backbone.Model} model
+ */
+ removeFromIndex: function (model) {
+ var index = this.index;
+ var doc = model.toJSON();
+ if (index.documentStore.has(doc[this.ref])) index.remove(doc);
+ },
+
+ /**
+ Updates the index for the given model.
+
+ @param {Backbone.Model} model
+ */
+ updateIndex: function (model) {
+ var changed = model.changedAttributes();
+ if (changed && !_.isEmpty(_.intersection(_.keys(this.fields),
+ _.keys(changed)))) {
+ this.index.update(model.toJSON());
+ }
+ },
+
+ /**
+ Takes the query from the search box and performs a full-text search on
+ the client-side. The search result is returned by resetting the
+ underlying collection to the models after interrogating the index for the
+ query answer.
+
+ If the collection is a PageableCollection, searching will go back to the
+ first page.
+ */
+ search: function () {
+ var col = this.collection;
+ if (!this.searchBox().val()) {
+ col.reset(this.shadowCollection.models, {reindex: false});
+ return;
+ }
+
+ var searchResults = this.index.search(this.searchBox().val());
+ var models = [];
+ for (var i = 0; i < searchResults.length; i++) {
+ var result = searchResults[i];
+ models.push(this.shadowCollection.get(result.ref));
+ }
+
+ if (col.pageableCollection) col.pageableCollection.getFirstPage({silent: true});
+ col.reset(models, {reindex: false});
+ }
+
+ });
+
+}));
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.min.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.min.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.min.js
new file mode 100644
index 0000000..3d8edfb
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-filter/js/backgrid-filter.min.js
@@ -0,0 +1,8 @@
+/*
+ backgrid-filter
+ http://github.com/wyuenho/backgrid
+
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+ Licensed under the MIT @license.
+*/
+!function(a,b){"object"==typeof exports?!function(){var a;try{a=require("lunr")}catch(c){}module.exports=b(require("underscore"),require("backbone"),require("backgrid"),a)}():b(a._,a.Backbone,a.Backgrid,a.lunr)}(this,function(a,b,c,d){"use strict";var e=c.Extension.ServerSideFilter=b.View.extend({tagName:"form",className:"backgrid-filter form-search",template:a.template('<span class="search"> </span><input type="search" <% if (placeholder) { %> placeholder="<%- placeholder %>" <% } %> name="<%- name %>" /><a class="clear" data-backgrid-action="clear" href="#">×</a>',null,{variable:null}),events:{"keyup input[type=search]":"showClearButtonMaybe","click a[data-backgrid-action=clear]":"clear",submit:"search"},name:"q",placeholder:null,initialize:function(a){e.__super__.initialize.apply(this,arguments),this.name=a.name||this.name,this.placeholder=a.placeholder||this.placeholder,this.template=a.template||this.template;var c=this.collection,d=this;b.PageableCollection&&c instan
ceof b.PageableCollection&&"server"==c.mode&&(c.queryParams[this.name]=function(){return d.searchBox().val()||null})},showClearButtonMaybe:function(){var a=this.clearButton(),b=this.searchBox().val();b?a.show():a.hide()},searchBox:function(){return this.$el.find("input[type=search]")},clearButton:function(){return this.$el.find("a[data-backgrid-action=clear]")},search:function(a){a&&a.preventDefault();var c={},d=this.searchBox().val();d&&(c[this.name]=d);var e=this.collection;b.PageableCollection&&e instanceof b.PageableCollection?e.getFirstPage({data:c,reset:!0,fetch:!0}):e.fetch({data:c,reset:!0})},clear:function(a){a&&a.preventDefault(),this.searchBox().val(null),this.showClearButtonMaybe();var c=this.collection;b.PageableCollection&&c instanceof b.PageableCollection?c.getFirstPage({reset:!0,fetch:!0}):c.fetch({reset:!0})},render:function(){return this.$el.empty().append(this.template({name:this.name,placeholder:this.placeholder,value:this.value})),this.showClearButtonMaybe(),thi
s.delegateEvents(),this}}),f=c.Extension.ClientSideFilter=e.extend({events:a.extend({},e.prototype.events,{"click a[data-backgrid-action=clear]":function(a){a.preventDefault(),this.clear()},"keydown input[type=search]":"search",submit:function(a){a.preventDefault(),this.search()}}),fields:null,wait:149,initialize:function(b){f.__super__.initialize.apply(this,arguments),this.fields=b.fields||this.fields,this.wait=b.wait||this.wait,this._debounceMethods(["search","clear"]);var c=this.collection=this.collection.fullCollection||this.collection,d=this.shadowCollection=c.clone();this.listenTo(c,"add",function(a,b,c){d.add(a,c)}),this.listenTo(c,"remove",function(a,b,c){d.remove(a,c)}),this.listenTo(c,"sort",function(a){this.searchBox().val()||d.reset(a.models)}),this.listenTo(c,"reset",function(b,c){c=a.extend({reindex:!0},c||{}),c.reindex&&null==c.from&&null==c.to&&d.reset(b.models)})},_debounceMethods:function(b){a.isString(b)&&(b=[b]),this.undelegateEvents();for(var c=0,d=b.length;d>c;
c++){var e=b[c],f=this[e];this[e]=a.debounce(f,this.wait)}this.delegateEvents()},makeRegExp:function(a){return new RegExp(a.trim().split(/\s+/).join("|"),"i")},makeMatcher:function(a){var b=this.makeRegExp(a);return function(a){for(var c=this.fields||a.keys(),d=0,e=c.length;e>d;d++)if(b.test(a.get(c[d])+""))return!0;return!1}},search:function(){var b=a.bind(this.makeMatcher(this.searchBox().val()),this),c=this.collection;c.pageableCollection&&c.pageableCollection.getFirstPage({silent:!0}),c.reset(this.shadowCollection.filter(b),{reindex:!1})},clear:function(){this.searchBox().val(null),this.showClearButtonMaybe();var a=this.collection;a.pageableCollection&&a.pageableCollection.getFirstPage({silent:!0}),a.reset(this.shadowCollection.models,{reindex:!1})}}),g=c.Extension.LunrFilter=f.extend({ref:"id",fields:null,initialize:function(a){g.__super__.initialize.apply(this,arguments),this.ref=a.ref||this.ref;var b=this.collection=this.collection.fullCollection||this.collection;this.listenT
o(b,"add",this.addToIndex),this.listenTo(b,"remove",this.removeFromIndex),this.listenTo(b,"reset",this.resetIndex),this.listenTo(b,"change",this.updateIndex),this.resetIndex(b)},resetIndex:function(b,c){if(c=a.extend({reindex:!0},c||{}),c.reindex){var e=this;this.index=d(function(){a.each(e.fields,function(a,b){this.field(b,a),this.ref(e.ref)},this)}),b.each(function(a){this.addToIndex(a)},this)}},addToIndex:function(a){var b=this.index,c=a.toJSON();b.documentStore.has(c[this.ref])?b.update(c):b.add(c)},removeFromIndex:function(a){var b=this.index,c=a.toJSON();b.documentStore.has(c[this.ref])&&b.remove(c)},updateIndex:function(b){var c=b.changedAttributes();c&&!a.isEmpty(a.intersection(a.keys(this.fields),a.keys(c)))&&this.index.update(b.toJSON())},search:function(){var a=this.collection;if(!this.searchBox().val())return void a.reset(this.shadowCollection.models,{reindex:!1});for(var b=this.index.search(this.searchBox().val()),c=[],d=0;d<b.length;d++){var e=b[d];c.push(this.shadowCo
llection.get(e.ref))}a.pageableCollection&&a.pageableCollection.getFirstPage({silent:!0}),a.reset(c,{reindex:!1})}})});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/css/backgrid-paginator.css
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/css/backgrid-paginator.css b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/css/backgrid-paginator.css
new file mode 100644
index 0000000..20ebbd2
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/css/backgrid-paginator.css
@@ -0,0 +1,58 @@
+/*
+ backgrid-paginator
+ http://github.com/wyuenho/backgrid
+
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+ Licensed under the MIT license.
+*/
+
+.backgrid-paginator {
+ text-align: center;
+ border-top: none;
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.backgrid-paginator ul {
+ display: inline-block;
+ *display: inline;
+ margin: 5px 0;
+ *zoom: 1;
+}
+
+.backgrid-paginator ul > li {
+ display: inline;
+}
+
+.backgrid-paginator ul > li > a,
+.backgrid-paginator ul > li > span {
+ float: left;
+ width: 30px;
+ height: 30px;
+ padding: 0;
+ line-height: 30px;
+ text-decoration: none;
+}
+
+.backgrid-paginator ul > li > a:hover,
+.backgrid-paginator ul > .active > a,
+.backgrid-paginator ul > .active > span {
+ background-color: #f5f5f5;
+}
+
+.backgrid-paginator ul > .active > a,
+.backgrid-paginator ul > .active > span {
+ color: #999999;
+ cursor: default;
+}
+
+.backgrid-paginator ul > .disabled > span,
+.backgrid-paginator ul > .disabled > a,
+.backgrid-paginator ul > .disabled > a:hover {
+ color: #999999;
+ cursor: default;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f7294694/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.js
new file mode 100644
index 0000000..a0b3af9
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.js
@@ -0,0 +1,427 @@
+/*
+ backgrid-paginator
+ http://github.com/wyuenho/backgrid
+
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+ Licensed under the MIT @license.
+*/
+(function (root, factory) {
+
+ // CommonJS
+ if (typeof exports == "object") {
+ module.exports = factory(require("underscore"),
+ require("backbone"),
+ require("backgrid"),
+ require("backbone-pageable"));
+ }
+ // Browser
+ else {
+ factory(root._, root.Backbone, root.Backgrid);
+ }
+
+}(this, function (_, Backbone, Backgrid) {
+
+ "use strict";
+
+ /**
+ PageHandle is a class that renders the actual page handles and reacts to
+ click events for pagination.
+
+ This class acts in two modes - control or discrete page handle modes. If
+ one of the `is*` flags is `true`, an instance of this class is under
+ control page handle mode. Setting a `pageIndex` to an instance of this
+ class under control mode has no effect and the correct page index will
+ always be inferred from the `is*` flag. Only one of the `is*` flags should
+ be set to `true` at a time. For example, an instance of this class cannot
+ simultaneously be a rewind control and a fast forward control. A `label`
+ and a `title` template or a string are required to be passed to the
+ constuctor under this mode. If a `title` template is provided, it __MUST__
+ accept a parameter `label`. When the `label` is provided to the `title`
+ template function, its result will be used to render the generated anchor's
+ title attribute.
+
+ If all of the `is*` flags is set to `false`, which is the default, an
+ instance of this class will be in discrete page handle mode. An instance
+ under this mode requires the `pageIndex` to be passed from the constructor
+ as an option and it __MUST__ be a 0-based index of the list of page numbers
+ to render. The constuctor will normalize the base to the same base the
+ underlying PageableCollection collection instance uses. A `label` is not
+ required under this mode, which will default to the equivalent 1-based page
+ index calculated from `pageIndex` and the underlying PageableCollection
+ instance. A provided `label` will still be honored however. The `title`
+ parameter is also not required under this mode, in which case the default
+ `title` template will be used. You are encouraged to provide your own
+ `title` template however if you wish to localize the title strings.
+
+ If this page handle represents the current page, an `active` class will be
+ placed on the root list element.
+
+ If this page handle is at the border of the list of pages, a `disabled`
+ class will be placed on the root list element.
+
+ Only page handles that are neither `active` nor `disabled` will respond to
+ click events and triggers pagination.
+
+ @class Backgrid.Extension.PageHandle
+ */
+ var PageHandle = Backgrid.Extension.PageHandle = Backbone.View.extend({
+
+ /** @property */
+ tagName: "li",
+
+ /** @property */
+ events: {
+ "click a": "changePage"
+ },
+
+ /**
+ @property {string|function(Object.<string, string>): string} title
+ The title to use for the `title` attribute of the generated page handle
+ anchor elements. It can be a string or an Underscore template function
+ that takes a mandatory `label` parameter.
+ */
+ title: _.template('Page <%- label %>', null, {variable: null}),
+
+ /**
+ @property {boolean} isRewind Whether this handle represents a rewind
+ control
+ */
+ isRewind: false,
+
+ /**
+ @property {boolean} isBack Whether this handle represents a back
+ control
+ */
+ isBack: false,
+
+ /**
+ @property {boolean} isForward Whether this handle represents a forward
+ control
+ */
+ isForward: false,
+
+ /**
+ @property {boolean} isFastForward Whether this handle represents a fast
+ forward control
+ */
+ isFastForward: false,
+
+ /**
+ Initializer.
+
+ @param {Object} options
+ @param {Backbone.Collection} options.collection
+ @param {number} pageIndex 0-based index of the page number this handle
+ handles. This parameter will be normalized to the base the underlying
+ PageableCollection uses.
+ @param {string} [options.label] If provided it is used to render the
+ anchor text, otherwise the normalized pageIndex will be used
+ instead. Required if any of the `is*` flags is set to `true`.
+ @param {string} [options.title]
+ @param {boolean} [options.isRewind=false]
+ @param {boolean} [options.isBack=false]
+ @param {boolean} [options.isForward=false]
+ @param {boolean} [options.isFastForward=false]
+ */
+ initialize: function (options) {
+ var collection = this.collection;
+ var state = collection.state;
+ var currentPage = state.currentPage;
+ var firstPage = state.firstPage;
+ var lastPage = state.lastPage;
+
+ _.extend(this, _.pick(options,
+ ["isRewind", "isBack", "isForward", "isFastForward"]));
+
+ var pageIndex;
+ if (this.isRewind) pageIndex = firstPage;
+ else if (this.isBack) pageIndex = Math.max(firstPage, currentPage - 1);
+ else if (this.isForward) pageIndex = Math.min(lastPage, currentPage + 1);
+ else if (this.isFastForward) pageIndex = lastPage;
+ else {
+ pageIndex = +options.pageIndex;
+ pageIndex = (firstPage ? pageIndex + 1 : pageIndex);
+ }
+ this.pageIndex = pageIndex;
+
+ this.label = (options.label || (firstPage ? pageIndex : pageIndex + 1)) + '';
+ var title = options.title || this.title;
+ this.title = _.isFunction(title) ? title({label: this.label}) : title;
+ },
+
+ /**
+ Renders a clickable anchor element under a list item.
+ */
+ render: function () {
+ this.$el.empty();
+ var anchor = document.createElement("a");
+ anchor.href = '#';
+ if (this.title) anchor.title = this.title;
+ anchor.innerHTML = this.label;
+ this.el.appendChild(anchor);
+
+ var collection = this.collection;
+ var state = collection.state;
+ var currentPage = state.currentPage;
+ var pageIndex = this.pageIndex;
+
+ if (this.isRewind && currentPage == state.firstPage ||
+ this.isBack && !collection.hasPrevious() ||
+ this.isForward && !collection.hasNext() ||
+ this.isFastForward && (currentPage == state.lastPage || state.totalPages < 1)) {
+ this.$el.addClass("disabled");
+ }
+ else if (!(this.isRewind ||
+ this.isBack ||
+ this.isForward ||
+ this.isFastForward) &&
+ state.currentPage == pageIndex) {
+ this.$el.addClass("active");
+ }
+
+ this.delegateEvents();
+ return this;
+ },
+
+ /**
+ jQuery click event handler. Goes to the page this PageHandle instance
+ represents. No-op if this page handle is currently active or disabled.
+ */
+ changePage: function (e) {
+ e.preventDefault();
+ var $el = this.$el, col = this.collection;
+ if (!$el.hasClass("active") && !$el.hasClass("disabled")) {
+ if (this.isRewind) col.getFirstPage();
+ else if (this.isBack) col.getPreviousPage();
+ else if (this.isForward) col.getNextPage();
+ else if (this.isFastForward) col.getLastPage();
+ else col.getPage(this.pageIndex, {reset: true});
+ }
+ return this;
+ }
+
+ });
+
+ /**
+ Paginator is a Backgrid extension that renders a series of configurable
+ pagination handles. This extension is best used for splitting a large data
+ set across multiple pages. If the number of pages is larger then a
+ threshold, which is set to 10 by default, the page handles are rendered
+ within a sliding window, plus the rewind, back, forward and fast forward
+ control handles. The individual control handles can be turned off.
+
+ @class Backgrid.Extension.Paginator
+ */
+ var Paginator = Backgrid.Extension.Paginator = Backbone.View.extend({
+
+ /** @property */
+ className: "backgrid-paginator",
+
+ /** @property */
+ windowSize: 10,
+
+ /**
+ @property {number} slideScale the number used by #slideHowMuch to scale
+ `windowSize` to yield the number of pages to slide. For example, the
+ default windowSize(10) * slideScale(0.5) yields 5, which means the window
+ will slide forward 5 pages as soon as you've reached page 6. The smaller
+ the scale factor the less pages to slide, and vice versa.
+
+ Also See:
+
+ - #slideMaybe
+ - #slideHowMuch
+ */
+ slideScale: 0.5,
+
+ /**
+ @property {Object.<string, Object.<string, string>>} controls You can
+ disable specific control handles by setting the keys in question to
+ null. The defaults will be merged with your controls object, with your
+ changes taking precedent.
+ */
+ controls: {
+ rewind: {
+ label: "《",
+ title: "First"
+ },
+ back: {
+ label: "〈",
+ title: "Previous"
+ },
+ forward: {
+ label: "〉",
+ title: "Next"
+ },
+ fastForward: {
+ label: "》",
+ title: "Last"
+ }
+ },
+
+ /** @property */
+ renderIndexedPageHandles: true,
+
+ /**
+ @property {Backgrid.Extension.PageHandle} pageHandle. The PageHandle
+ class to use for rendering individual handles
+ */
+ pageHandle: PageHandle,
+
+ /** @property */
+ goBackFirstOnSort: true,
+
+ /**
+ Initializer.
+
+ @param {Object} options
+ @param {Backbone.Collection} options.collection
+ @param {boolean} [options.controls]
+ @param {boolean} [options.pageHandle=Backgrid.Extension.PageHandle]
+ @param {boolean} [options.goBackFirstOnSort=true]
+ */
+ initialize: function (options) {
+ var self = this;
+ self.controls = _.defaults(options.controls || {}, self.controls,
+ Paginator.prototype.controls);
+
+ _.extend(self, _.pick(options || {}, "windowSize", "pageHandle",
+ "slideScale", "goBackFirstOnSort",
+ "renderIndexedPageHandles"));
+
+ var col = self.collection;
+ self.listenTo(col, "add", self.render);
+ self.listenTo(col, "remove", self.render);
+ self.listenTo(col, "reset", self.render);
+ self.listenTo(col, "backgrid:sorted", function () {
+ if (self.goBackFirstOnSort) col.getFirstPage({reset: true});
+ });
+ },
+
+ /**
+ Decides whether the window should slide. This method should return 1 if
+ sliding should occur and 0 otherwise. The default is sliding should occur
+ if half of the pages in a window has been reached.
+
+ __Note__: All the parameters have been normalized to be 0-based.
+
+ @param {number} firstPage
+ @param {number} lastPage
+ @param {number} currentPage
+ @param {number} windowSize
+ @param {number} slideScale
+
+ @return {0|1}
+ */
+ slideMaybe: function (firstPage, lastPage, currentPage, windowSize, slideScale) {
+ return Math.round(currentPage % windowSize / windowSize);
+ },
+
+ /**
+ Decides how many pages to slide when sliding should occur. The default
+ simply scales the `windowSize` to arrive at a fraction of the `windowSize`
+ to increment.
+
+ __Note__: All the parameters have been normalized to be 0-based.
+
+ @param {number} firstPage
+ @param {number} lastPage
+ @param {number} currentPage
+ @param {number} windowSize
+ @param {number} slideScale
+
+ @return {number}
+ */
+ slideThisMuch: function (firstPage, lastPage, currentPage, windowSize, slideScale) {
+ return ~~(windowSize * slideScale);
+ },
+
+ _calculateWindow: function () {
+ var collection = this.collection;
+ var state = collection.state;
+
+ // convert all indices to 0-based here
+ var firstPage = state.firstPage;
+ var lastPage = +state.lastPage;
+ lastPage = Math.max(0, firstPage ? lastPage - 1 : lastPage);
+ var currentPage = Math.max(state.currentPage, state.firstPage);
+ currentPage = firstPage ? currentPage - 1 : currentPage;
+ var windowSize = this.windowSize;
+ var slideScale = this.slideScale;
+ var windowStart = Math.floor(currentPage / windowSize) * windowSize;
+ if (currentPage <= lastPage - this.slideThisMuch()) {
+ windowStart += (this.slideMaybe(firstPage, lastPage, currentPage, windowSize, slideScale) *
+ this.slideThisMuch(firstPage, lastPage, currentPage, windowSize, slideScale));
+ }
+ var windowEnd = Math.min(lastPage + 1, windowStart + windowSize);
+ return [windowStart, windowEnd];
+ },
+
+ /**
+ Creates a list of page handle objects for rendering.
+
+ @return {Array.<Object>} an array of page handle objects hashes
+ */
+ makeHandles: function () {
+
+ var handles = [];
+ var collection = this.collection;
+
+ var window = this._calculateWindow();
+ var winStart = window[0], winEnd = window[1];
+
+ if (this.renderIndexedPageHandles) {
+ for (var i = winStart; i < winEnd; i++) {
+ handles.push(new this.pageHandle({
+ collection: collection,
+ pageIndex: i
+ }));
+ }
+ }
+
+ var controls = this.controls;
+ _.each(["back", "rewind", "forward", "fastForward"], function (key) {
+ var value = controls[key];
+ if (value) {
+ var handleCtorOpts = {
+ collection: collection,
+ title: value.title,
+ label: value.label
+ };
+ handleCtorOpts["is" + key.slice(0, 1).toUpperCase() + key.slice(1)] = true;
+ var handle = new this.pageHandle(handleCtorOpts);
+ if (key == "rewind" || key == "back") handles.unshift(handle);
+ else handles.push(handle);
+ }
+ }, this);
+
+ return handles;
+ },
+
+ /**
+ Render the paginator handles inside an unordered list.
+ */
+ render: function () {
+ this.$el.empty();
+
+ if (this.handles) {
+ for (var i = 0, l = this.handles.length; i < l; i++) {
+ this.handles[i].remove();
+ }
+ }
+
+ var handles = this.handles = this.makeHandles();
+
+ var ul = document.createElement("ul");
+ for (var i = 0; i < handles.length; i++) {
+ ul.appendChild(handles[i].render().el);
+ }
+
+ this.el.appendChild(ul);
+
+ return this;
+ }
+
+ });
+
+}));