http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.min.js ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.min.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.min.js new file mode 100644 index 0000000..8f9fd39 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-paginator/js/backgrid-paginator.min.js @@ -0,0 +1,8 @@ +/* + backgrid-paginator + 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?module.exports=b(require("underscore"),require("backbone"),require("backgrid"),require("backbone-pageable")):b(a._,a.Backbone,a.Backgrid)}(this,function(a,b,c){"use strict";var d=c.Extension.PageHandle=b.View.extend({tagName:"li",events:{"click a":"changePage"},title:a.template("Page <%- label %>",null,{variable:null}),isRewind:!1,isBack:!1,isForward:!1,isFastForward:!1,initialize:function(b){var c=this.collection,d=c.state,e=d.currentPage,f=d.firstPage,g=d.lastPage;a.extend(this,a.pick(b,["isRewind","isBack","isForward","isFastForward"]));var h;this.isRewind?h=f:this.isBack?h=Math.max(f,e-1):this.isForward?h=Math.min(g,e+1):this.isFastForward?h=g:(h=+b.pageIndex,h=f?h+1:h),this.pageIndex=h,this.label=(b.label||(f?h:h+1))+"";var i=b.title||this.title;this.title=a.isFunction(i)?i({label:this.label}):i},render:function(){this.$el.empty();var a=document.createElement("a");a.href="#",this.title&&(a.title=this.title),a.innerHTML=this.label,this.el. appendChild(a);var b=this.collection,c=b.state,d=c.currentPage,e=this.pageIndex;return this.isRewind&&d==c.firstPage||this.isBack&&!b.hasPrevious()||this.isForward&&!b.hasNext()||this.isFastForward&&(d==c.lastPage||c.totalPages<1)?this.$el.addClass("disabled"):this.isRewind||this.isBack||this.isForward||this.isFastForward||c.currentPage!=e||this.$el.addClass("active"),this.delegateEvents(),this},changePage:function(a){a.preventDefault();var b=this.$el,c=this.collection;return b.hasClass("active")||b.hasClass("disabled")||(this.isRewind?c.getFirstPage():this.isBack?c.getPreviousPage():this.isForward?c.getNextPage():this.isFastForward?c.getLastPage():c.getPage(this.pageIndex,{reset:!0})),this}}),e=c.Extension.Paginator=b.View.extend({className:"backgrid-paginator",windowSize:10,slideScale:.5,controls:{rewind:{label:"ã",title:"First"},back:{label:"ã",title:"Previous"},forward:{label:"ã",title:"Next"},fastForward:{label:"ã",title:"Last"}},renderIndexedPageHandles:!0,pageHandle:d ,goBackFirstOnSort:!0,initialize:function(b){var c=this;c.controls=a.defaults(b.controls||{},c.controls,e.prototype.controls),a.extend(c,a.pick(b||{},"windowSize","pageHandle","slideScale","goBackFirstOnSort","renderIndexedPageHandles"));var d=c.collection;c.listenTo(d,"add",c.render),c.listenTo(d,"remove",c.render),c.listenTo(d,"reset",c.render),c.listenTo(d,"backgrid:sorted",function(){c.goBackFirstOnSort&&d.getFirstPage({reset:!0})})},slideMaybe:function(a,b,c,d){return Math.round(c%d/d)},slideThisMuch:function(a,b,c,d,e){return~~(d*e)},_calculateWindow:function(){var a=this.collection,b=a.state,c=b.firstPage,d=+b.lastPage;d=Math.max(0,c?d-1:d);var e=Math.max(b.currentPage,b.firstPage);e=c?e-1:e;var f=this.windowSize,g=this.slideScale,h=Math.floor(e/f)*f;e<=d-this.slideThisMuch()&&(h+=this.slideMaybe(c,d,e,f,g)*this.slideThisMuch(c,d,e,f,g));var i=Math.min(d+1,h+f);return[h,i]},makeHandles:function(){var b=[],c=this.collection,d=this._calculateWindow(),e=d[0],f=d[1];if(this.rende rIndexedPageHandles)for(var g=e;f>g;g++)b.push(new this.pageHandle({collection:c,pageIndex:g}));var h=this.controls;return a.each(["back","rewind","forward","fastForward"],function(a){var d=h[a];if(d){var e={collection:c,title:d.title,label:d.label};e["is"+a.slice(0,1).toUpperCase()+a.slice(1)]=!0;var f=new this.pageHandle(e);"rewind"==a||"back"==a?b.unshift(f):b.push(f)}},this),b},render:function(){if(this.$el.empty(),this.handles)for(var a=0,b=this.handles.length;b>a;a++)this.handles[a].remove();for(var c=this.handles=this.makeHandles(),d=document.createElement("ul"),a=0;a<c.length;a++)d.appendChild(c[a].render().el);return this.el.appendChild(d),this}})}); \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.js ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.js new file mode 100644 index 0000000..1777f11 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.js @@ -0,0 +1,274 @@ +/* + backgrid-select-all + 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("backbone"), require("backgrid")); + } + // Browser + else factory(root.Backbone, root.Backgrid); + +}(this, function (Backbone, Backgrid) { + + "use strict"; + + /** + Renders a checkbox for row selection. + + @class Backgrid.Extension.SelectRowCell + @extends Backbone.View + */ + var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({ + + /** @property */ + className: "select-row-cell", + + /** @property */ + tagName: "td", + + /** @property */ + events: { + "keydown input[type=checkbox]": "onKeydown", + "change input[type=checkbox]": "onChange", + "click input[type=checkbox]": "enterEditMode" + }, + + /** + Initializer. If the underlying model triggers a `select` event, this cell + will change its checked value according to the event's `selected` value. + + @param {Object} options + @param {Backgrid.Column} options.column + @param {Backbone.Model} options.model + */ + initialize: function (options) { + + this.column = options.column; + if (!(this.column instanceof Backgrid.Column)) { + this.column = new Backgrid.Column(this.column); + } + + var column = this.column, model = this.model, $el = this.$el; + this.listenTo(column, "change:renderable", function (column, renderable) { + $el.toggleClass("renderable", renderable); + }); + + if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass("renderable"); + + this.listenTo(model, "backgrid:select", function (model, selected) { + this.$el.find("input[type=checkbox]").prop("checked", selected).change(); + }); + }, + + /** + Focuses the checkbox. + */ + enterEditMode: function () { + this.$el.find("input[type=checkbox]").focus(); + }, + + /** + Unfocuses the checkbox. + */ + exitEditMode: function () { + this.$el.find("input[type=checkbox]").blur(); + }, + + /** + Process keyboard navigation. + */ + onKeydown: function (e) { + var command = new Backgrid.Command(e); + if (command.passThru()) return true; // skip ahead to `change` + if (command.cancel()) { + e.stopPropagation(); + this.$el.find("input[type=checkbox]").blur(); + } + else if (command.save() || command.moveLeft() || command.moveRight() || + command.moveUp() || command.moveDown()) { + e.preventDefault(); + e.stopPropagation(); + this.model.trigger("backgrid:edited", this.model, this.column, command); + } + }, + + /** + When the checkbox's value changes, this method will trigger a Backbone + `backgrid:selected` event with a reference of the model and the + checkbox's `checked` value. + */ + onChange: function () { + var checked = this.$el.find("input[type=checkbox]").prop("checked"); + this.$el.parent().toggleClass("selected", checked); + this.model.trigger("backgrid:selected", this.model, checked); + }, + + /** + Renders a checkbox in a table cell. + */ + render: function () { + this.$el.empty().append('<input tabindex="-1" type="checkbox" />'); + this.delegateEvents(); + return this; + } + + }); + + /** + Renders a checkbox to select all rows on the current page. + + @class Backgrid.Extension.SelectAllHeaderCell + @extends Backgrid.Extension.SelectRowCell + */ + var SelectAllHeaderCell = Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({ + + /** @property */ + className: "select-all-header-cell", + + /** @property */ + tagName: "th", + + /** + Initializer. When this cell's checkbox is checked, a Backbone + `backgrid:select` event will be triggered for each model for the current + page in the underlying collection. If a `SelectRowCell` instance exists + for the rows representing the models, they will check themselves. If any + of the SelectRowCell instances trigger a Backbone `backgrid:selected` + event with a `false` value, this cell will uncheck its checkbox. In the + event of a Backbone `backgrid:refresh` event, which is triggered when the + body refreshes its rows, which can happen under a number of conditions + such as paging or the columns were reset, this cell will still remember + the previously selected models and trigger a Backbone `backgrid:select` + event on them such that the SelectRowCells can recheck themselves upon + refreshing. + + @param {Object} options + @param {Backgrid.Column} options.column + @param {Backbone.Collection} options.collection + */ + initialize: function (options) { + + this.column = options.column; + if (!(this.column instanceof Backgrid.Column)) { + this.column = new Backgrid.Column(this.column); + } + + var collection = this.collection; + var selectedModels = this.selectedModels = {}; + this.listenTo(collection.fullCollection || collection, + "backgrid:selected", function (model, selected) { + if (selected) selectedModels[model.id || model.cid] = 1; + else { + delete selectedModels[model.id || model.cid]; + this.$el.find("input[type=checkbox]").prop("checked", false); + } + }); + + this.listenTo(collection.fullCollection || collection, "remove", function (model) { + delete selectedModels[model.id || model.cid]; + }); + + this.listenTo(collection, "backgrid:refresh", function () { + var checked = this.$el.find("input[type=checkbox]").prop("checked"); + for (var i = 0; i < collection.length; i++) { + var model = collection.at(i); + if (checked || selectedModels[model.id || model.cid]) { + model.trigger("backgrid:select", model, true); + } + } + }); + + var column = this.column, $el = this.$el; + this.listenTo(column, "change:renderable", function (column, renderable) { + $el.toggleClass("renderable", renderable); + }); + + if (Backgrid.callByNeed(column.renderable(), column, collection)) $el.addClass("renderable"); + }, + + /** + Propagates the checked value of this checkbox to all the models of the + underlying collection by triggering a Backbone `backgrid:select` event on + the models on the current page, passing each model and the current + `checked` value of the checkbox in each event. + + A `backgrid:selected` event will also be triggered with the current + `checked` value on all the models regardless of whether they are on the + current page. + + This method triggers a 'backgrid:select-all' event on the collection + afterwards. + */ + onChange: function () { + var checked = this.$el.find("input[type=checkbox]").prop("checked"); + + var collection = this.collection; + collection.each(function (model) { + model.trigger("backgrid:select", model, checked); + }); + + if (collection.fullCollection) { + collection.fullCollection.each(function (model) { + if (!collection.get(model.cid)) { + model.trigger("backgrid:selected", model, checked); + } + }); + } + + this.collection.trigger("backgrid:select-all", this.collection, checked); + } + + }); + + /** + Convenient method to retrieve a list of selected models. This method only + exists when the `SelectAll` extension has been included. Selected models + are retained across pagination. + + @member Backgrid.Grid + @return {Array.<Backbone.Model>} + */ + Backgrid.Grid.prototype.getSelectedModels = function () { + var selectAllHeaderCell; + var headerCells = this.header.row.cells; + for (var i = 0, l = headerCells.length; i < l; i++) { + var headerCell = headerCells[i]; + if (headerCell instanceof SelectAllHeaderCell) { + selectAllHeaderCell = headerCell; + break; + } + } + + var result = []; + if (selectAllHeaderCell) { + var selectedModels = selectAllHeaderCell.selectedModels; + var collection = this.collection.fullCollection || this.collection; + for (var modelId in selectedModels) { + result.push(collection.get(modelId)); + } + } + + return result; + }; + + /** + Convenient method to deselect the selected models. This method is only + available when the `SelectAll` extension has been included. + + @member Backgrid.Grid + */ + Backgrid.Grid.prototype.clearSelectedModels = function () { + var selectedModels = this.getSelectedModels(); + for (var i = 0, l = selectedModels.length; i < l; i++) { + var model = selectedModels[i]; + model.trigger("backgrid:select", model, false); + } + }; + +})); http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.min.js ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.min.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.min.js new file mode 100644 index 0000000..1e49adf --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-select-all/js/backgrid-select-all.min.js @@ -0,0 +1,8 @@ +/* + backgrid-select-all + 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?module.exports=b(require("backbone"),require("backgrid")):b(a.Backbone,a.Backgrid)}(this,function(a,b){"use strict";var c=b.Extension.SelectRowCell=a.View.extend({className:"select-row-cell",tagName:"td",events:{"keydown input[type=checkbox]":"onKeydown","change input[type=checkbox]":"onChange","click input[type=checkbox]":"enterEditMode"},initialize:function(a){this.column=a.column,this.column instanceof b.Column||(this.column=new b.Column(this.column));var c=this.column,d=this.model,e=this.$el;this.listenTo(c,"change:renderable",function(a,b){e.toggleClass("renderable",b)}),b.callByNeed(c.renderable(),c,d)&&e.addClass("renderable"),this.listenTo(d,"backgrid:select",function(a,b){this.$el.find("input[type=checkbox]").prop("checked",b).change()})},enterEditMode:function(){this.$el.find("input[type=checkbox]").focus()},exitEditMode:function(){this.$el.find("input[type=checkbox]").blur()},onKeydown:function(a){var c=new b.Command(a);return c.pas sThru()?!0:(c.cancel()?(a.stopPropagation(),this.$el.find("input[type=checkbox]").blur()):(c.save()||c.moveLeft()||c.moveRight()||c.moveUp()||c.moveDown())&&(a.preventDefault(),a.stopPropagation(),this.model.trigger("backgrid:edited",this.model,this.column,c)),void 0)},onChange:function(){var a=this.$el.find("input[type=checkbox]").prop("checked");this.$el.parent().toggleClass("selected",a),this.model.trigger("backgrid:selected",this.model,a)},render:function(){return this.$el.empty().append('<input tabindex="-1" type="checkbox" />'),this.delegateEvents(),this}}),d=b.Extension.SelectAllHeaderCell=c.extend({className:"select-all-header-cell",tagName:"th",initialize:function(a){this.column=a.column,this.column instanceof b.Column||(this.column=new b.Column(this.column));var c=this.collection,d=this.selectedModels={};this.listenTo(c.fullCollection||c,"backgrid:selected",function(a,b){b?d[a.id||a.cid]=1:(delete d[a.id||a.cid],this.$el.find("input[type=checkbox]").prop("checked",!1))}),t his.listenTo(c.fullCollection||c,"remove",function(a){delete d[a.id||a.cid]}),this.listenTo(c,"backgrid:refresh",function(){for(var a=this.$el.find("input[type=checkbox]").prop("checked"),b=0;b<c.length;b++){var e=c.at(b);(a||d[e.id||e.cid])&&e.trigger("backgrid:select",e,!0)}});var e=this.column,f=this.$el;this.listenTo(e,"change:renderable",function(a,b){f.toggleClass("renderable",b)}),b.callByNeed(e.renderable(),e,c)&&f.addClass("renderable")},onChange:function(){var a=this.$el.find("input[type=checkbox]").prop("checked"),b=this.collection;b.each(function(b){b.trigger("backgrid:select",b,a)}),b.fullCollection&&b.fullCollection.each(function(c){b.get(c.cid)||c.trigger("backgrid:selected",c,a)}),this.collection.trigger("backgrid:select-all",this.collection,a)}});b.Grid.prototype.getSelectedModels=function(){for(var a,b=this.header.row.cells,c=0,e=b.length;e>c;c++){var f=b[c];if(f instanceof d){a=f;break}}var g=[];if(a){var h=a.selectedModels,i=this.collection.fullCollection||this.c ollection;for(var j in h)g.push(i.get(j))}return g},b.Grid.prototype.clearSelectedModels=function(){for(var a=this.getSelectedModels(),b=0,c=a.length;c>b;b++){var d=a[b];d.trigger("backgrid:select",d,!1)}}}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.css ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.css b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.css new file mode 100644 index 0000000..759f47c --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.css @@ -0,0 +1,34 @@ +/* + backgrid-orderable-columns + https://github.com/WRidder/backgrid-orderable-columns + + Copyright (c) 2014 Wilbert van de Ridder + Licensed under the MIT @license. + */ +.backgrid .orderable-indicator { + width: 3px; + top: 0; + position: absolute; + z-index: 1; +} + +.backgrid .orderable-indicator-active { + background-color: #000; /* IE8 fallback */ + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; /* IE8 fallback */ + background-color: rgba(0, 0, 0, 0.5); +} + +.backgrid thead th.orderable-ordering { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; /* IE8 fallback */ + opacity: 0.3; +} + +.backgrid .orderable-draggable { + position: absolute; + display: block; + background-color: #000; /* IE8 fallback */ + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; /* IE8 fallback */ + background-color: rgba(0, 0, 0, 0.1); + z-index: 3; + cursor: move; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.js ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.js new file mode 100644 index 0000000..03cbbd2 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/backgrid-orderable-columns.js @@ -0,0 +1,680 @@ +/* + backgrid-orderable-columns + https://github.com/WRidder/backgrid-orderable-columns + + Copyright (c) 2014 Wilbert van de Ridder + Licensed under the MIT @license. + */ +(function (root, factory) { + // CommonJS + if (typeof exports == "object") { + module.exports = factory(require("underscore"), require("backgrid"), require("jquery")); + } + // AMD. Register as an anonymous module. + else if (typeof define === 'function' && define.amd) { + define(['underscore', 'backgrid', 'jquery'], factory); + } + // Browser + else { + factory(root._, root.Backgrid, root.jQuery); + } +}(this, function (_, Backgrid, $) { + "use strict"; + + // Adds width support to columns + Backgrid.Extension.OrderableColumns = Backbone.View.extend({ + dragHooks: {}, + + /** + * Initializer + * @param options + */ + initialize: function (options) { + this.sizeAbleColumns = options.sizeAbleColumns; + this.grid = this.sizeAbleColumns.grid; + this.columns = this.grid.columns; + this.header = this.grid.header; + this.collection = this.grid.collection; + this.moveThreshold = options.moveThreshold || 10; + this.orderAlignTop = options.orderAlignTop; + + this.attachEvents(); + this.setHeaderElements(); + + // Set scope handlers + this.mouseMoveHandler = _.bind(this.mouseMoveHandler, this); + this.mouseUpHandler = _.bind(this.mouseUpHandler, this); + }, + + /** + * Adds handlers to reorder the columns + * @returns {Backgrid.Extension.OrderableColumns} + */ + render: function () { + var self = this; + self.$el.empty(); + + // Create indicators + self.addIndicators(); + + // Loop all rows + var headerRows = self.header.headerRows || [self.header.row]; + _.each(headerRows, function (row) { + // Loop cells of row + _.each(row.cells, function (cell) { + // Get column model + var columnModel = cell.column; + + // Attach handler if main orderable cell or has child + var orderable = false; + if (!columnModel.get("childColumns")) { + orderable = typeof columnModel.get("orderable") == "undefined" || columnModel.get("orderable"); + } + else { + // Parent element is orderable if any of the children is orderable + orderable = _.some(columnModel.get("childColumns"), function(child) { + var childColumnModel = child.column; + return typeof childColumnModel.get("orderable") == "undefined" || childColumnModel.get("orderable"); + }); + } + + // If orderable, add handler + if (orderable) { + cell.$el.on("mousedown", + _.bind(self.mouseDownHandler, { + view: self, + cell: cell, + column: columnModel + }) + ); + } + }); + }); + + // Position drag handlers + self.updateIndicatorPosition(); + + return this; + }, + + /** + * Drag state object + */ + dragState: { + dragIntention: false, + dragging: false, + $dragElement: null, + $activeIndicator: null, + column: null, + cell: null, + coordinateElementStartX: null, + coordinatePointerStartX: null, + oldFirstDisplayOrderValue: null, + oldLastDisplayOrderValue: null, + newDisplayOrderValue: null, + orderPrevented: null + }, + + mouseDownHandler: function(evt) { + var self = this.view; + var cell = this.cell; + var column = this.column; + var $headerElement = $(cell.$el); + + // Check if left-click + if (evt.which === 1) { + self._stopEvent(evt); + + // Set drag state + self.dragState.dragIntention = true; + self.dragState.column = column; + self.dragState.cell = cell; + self.dragState.coordinatePointerStartX = evt.pageX; + self.dragState.coordinateElementStartX = $headerElement.position().left; + + if (column.get("childColumns")) { + self.dragState.oldFirstDisplayOrderValue = _.first(column.get("childColumns")).column.get("displayOrder"); + self.dragState.newDisplayOrderValue = _.first(column.get("childColumns")).column.get("displayOrder"); + self.dragState.oldLastDisplayOrderValue = _.last(column.get("childColumns")).column.get("displayOrder"); + } + else { + self.dragState.oldFirstDisplayOrderValue = column.get("displayOrder"); + self.dragState.newDisplayOrderValue = column.get("displayOrder"); + self.dragState.oldLastDisplayOrderValue = column.get("displayOrder"); + } + + // Create copy of column element + self.dragState.$dragElement = $("<div/>") + .addClass("orderable-draggable") + .hide() + .appendTo(self.$el) + .width($headerElement.outerWidth()) + .height($headerElement.outerHeight()) + .css({ + left: $headerElement.position().left, + top: $headerElement.position().top + }); + + // Add move and mouse up handler + $(document).on("mousemove", self.mouseMoveHandler); + $(document).on("mouseup", self.mouseUpHandler); + } + }, + + /** + * Mouse move event handler + * @param evt + */ + mouseMoveHandler: function(evt) { + var self = this; + var pageX = evt.pageX; + var leftPosition = self.dragState.coordinateElementStartX + (pageX - self.dragState.coordinatePointerStartX); + self._stopEvent(evt); + var delta = Math.abs(pageX - self.dragState.coordinatePointerStartX); + + if (self.dragState.dragging) { + // Highlight nearest indicator + self.calculateDropPosition(leftPosition, evt); + + // Notify drag hooks + self.dragHookInvoke("dragMove", self.dragState.$dragElement, evt, self.dragState.column); + + // Set draggable eleent position + self.dragState.$dragElement.css({ + left: leftPosition + }); + } + // Only move beyond threshold + else if (delta >= self.moveThreshold && !self.dragState.dragging) { + self.dragState.cell.$el.addClass("orderable-ordering"); + self.dragState.dragging = true; + + // Notify drag hooks + self.dragHookInvoke("dragStart", evt, self.dragState.column); + + // Show and position drag element + self.dragState.$dragElement.css({ + left: leftPosition + }).show(); + } + }, + + /** + * Mouse up event handler + * @param evt + */ + mouseUpHandler: function(evt) { + var self = this; + + // Remove handlers + $(document).off("mousemove", self.mouseMoveHandler); + $(document).off("mouseup", self.mouseUpHandler); + + // Notify drag hooks + self.dragHookInvoke("dragEnd", evt, self.dragState.column); + + // Check if the columns have actually been re-ordered + if (!self.dragState.orderPrevented && + self.dragState.oldFirstDisplayOrderValue !== self.dragState.newDisplayOrderValue) { + + // Update positions + self.updateDisplayOrders(); + + // Trigger event indicating column reordering + self.columns.trigger("ordered"); + + // Sort columns + self.columns.sort(); + } + + // Reset drag state + self.resetDragState(); + }, + + /** + * Find the drop position for the current position of the dragged header element + * @param leftPosition + * @param evt + */ + calculateDropPosition: function(leftPosition, evt) { + var self = this; + + // Find closest indicator + var closest = null; + var $closestIndicator = null; + _.each(self.indicatorPositions, function (indicator, displayOrder) { + if (closest == null || + Math.abs(indicator.x - leftPosition) < Math.abs(closest - leftPosition) && + (displayOrder <= self.dragState.oldFirstDisplayOrderValue || displayOrder > self.dragState.oldLastDisplayOrderValue + 1) + ) { + closest = indicator.x; + $closestIndicator = indicator.$el; + } + }); + + // Set active class on current indicator + if ($closestIndicator !== self.dragState.$activeIndicator) { + if (self.dragState.$activeIndicator) { + self.dragState.$activeIndicator.removeClass('orderable-indicator-active'); + } + } + + // Check if the move is valid + if (!self.dragHookPreventOrder(self.dragState.$dragElement, evt, self.dragState.column)) { + // Set active class on current indicator + if ($closestIndicator !== self.dragState.$activeIndicator) { + if (self.dragState.$activeIndicator) { + self.dragState.$activeIndicator.removeClass('orderable-indicator-active'); + } + self.dragState.$activeIndicator = $closestIndicator; + $closestIndicator.addClass('orderable-indicator-active'); + + // Save new order + self.dragState.newDisplayOrderValue = $closestIndicator.data("column-displayOrder"); + } + self.dragState.orderPrevented = false; + } + else { + self.dragState.orderPrevented = true; + } + }, + + /** + * Calculates displayOrder attributes for columns after re-ordering + */ + updateDisplayOrders: function() { + var self = this; + var oldFirstDO = self.dragState.oldFirstDisplayOrderValue; + var oldLastDO = self.dragState.oldLastDisplayOrderValue; + var newDO = self.dragState.newDisplayOrderValue; + var movedRight = oldFirstDO < newDO; + var span = (oldLastDO - oldFirstDO) + 1; + var positionShift = (movedRight) ? (newDO - oldFirstDO - span) : (oldFirstDO - newDO); + + // Update position attributes + self.columns.each(function (model) { + var mDO = model.get("displayOrder"); + var nDO = mDO; + if (movedRight) { + if (mDO > oldLastDO && mDO < newDO) { + nDO = mDO - span; + } + else if (mDO >= oldFirstDO && mDO <= oldLastDO) { + nDO = mDO + positionShift; + } + } + else { + if (mDO >= newDO && mDO < oldFirstDO) { + nDO = mDO + span; + } + else if (mDO >= oldFirstDO && mDO <= oldLastDO) { + nDO = mDO - positionShift; + } + } + + // Update displayOrder value + if (mDO !== nDO) { + model.set("displayOrder", nDO, {silent: true}); + } + }); + }, + + /** + * Reset drag state + */ + resetDragState: function() { + this.dragState.dragging = false; + this.dragState.dragIntention = false; + if (this.dragState.cell) { + this.dragState.cell.$el.removeClass("orderable-ordering"); + this.dragState.cell = null; + } + if (this.dragState.$dragElement) { + this.dragState.$dragElement.remove(); + this.dragState.$dragElement = null; + } + if (this.dragState.$activeIndicator) { + this.dragState.$activeIndicator.removeClass('orderable-indicator-active'); + } + this.dragState.$activeIndicator = null; + this.dragState.column = null; + this.dragState.coordinateElementStartX = null; + this.dragState.coordinatePointerStartX = null; + this.dragState.orderPrevented = null; + }, + + /** + * Adds indicators which will show at which spot the column will be placed while dragging + * @private + */ + addIndicators: function () { + var self = this; + self.indicators = []; + + var previousIndicators = false; + var previousDisplayOrder = 0; + var previousRealDisplayOrder = 0; + _.each(self.headerCells, function (headerCell) { + var model = headerCell.column; + if (previousIndicators || model.get("orderable")) { + var DO = model.get("displayOrder"); + + if (!previousIndicators) { + previousDisplayOrder = previousRealDisplayOrder = DO - 1; + } + + // Check whether to add columns after front or tail when gaps exist. + if (!self.orderAlignTop && DO !== previousDisplayOrder + 1 && previousDisplayOrder === previousRealDisplayOrder) { + DO = previousDisplayOrder + 1; + } + self.$el.append(self.createIndicator(DO, headerCell)); + + // This boolean is used to see to what extend we can omit indicators upfront + previousIndicators = true; + previousDisplayOrder = DO; + previousRealDisplayOrder = model.get("displayOrder"); + } + }); + + // Add trailing indicator + if (!_.isEmpty(self.headerCells) && _.last(self.headerCells).column.get("orderable")) { + self.$el.append(self.createIndicator(_.last(self.headerCells).column.get("displayOrder") + 1, null)); + } + + // Set indicator height + self.setIndicatorHeight(self.grid.header.$el.height()); + }, + + /** + * Create a single indicator + * @param {Integer} displayOrder + * @returns {*|JQuery|any|jQuery} + * @private + */ + createIndicator: function (displayOrder, cell) { + var self = this; + + // Create helper elements + var $indicator = $("<div></div>") + .addClass("orderable-indicator") + .data("column-cell", cell) + .data("column-displayOrder", displayOrder); + self.indicators.push($indicator); + + return $indicator; + }, + + /** + * Updates the position of all handlers + * @private + */ + updateIndicatorPosition: function () { + var self = this; + self.indicatorPositions = {}; + + _.each(self.indicators, function ($indicator, indx) { + var cell = $indicator.data("column-cell"); + var displayOrder = $indicator.data("column-displayOrder"); + + var left; + if (cell) { + left = cell.$el.position().left; + } + else { + var prevCell = self.indicators[indx - 1].data("column-cell"); + left = prevCell.$el.position().left + prevCell.$el.width(); + } + self.indicatorPositions[displayOrder] = { + x: left, + $el: $indicator + }; + + // Get handler for current column and update position + $indicator.css("left", left); + }); + self.setIndicatorHeight(); + }, + + /** + * Sets height of all indicators matching the table header + * @private + */ + setIndicatorHeight: function () { + this.$el.children().height(this.grid.header.$el.height()); + }, + + /** + * Attach event handlers + * @private + */ + attachEvents: function () { + var self = this; + self.listenTo(self.columns, "resize", self.handleColumnResize); + self.listenTo(self.columns, "remove", self.handleColumnRemove); + self.listenTo(self.columns, "sort", self.handleColumnSort); + self.listenTo(self.grid.collection, "backgrid:colgroup:updated", self.updateIndicatorPosition); + self.listenTo(self.grid.collection, "backgrid:colgroup:changed", self.handleHeaderRender); + + // Listen to window resize events + var resizeEvtHandler = _.debounce(_.bind(self.updateIndicatorPosition, self), 250); + self.listenTo(self._asEvents(window), "resize", resizeEvtHandler); + }, + + /** + * Handlers when columns are resized + * @private + */ + handleColumnResize: function () { + var self = this; + self.updateIndicatorPosition(); + self.setIndicatorHeight(); + }, + + /** + * Handler when header is (re)rendered + * @private + */ + handleHeaderRender: function () { + var self = this; + // Wait for callstack to be cleared + _.defer(function () { + self.setHeaderElements(); + self.render(); + self.updateIndicatorPosition(); + }); + }, + + /** + * Handler for when a column is removed + * @param {Backgrid.Column} model + * @param {Backgrid.Columns} collection + * @private + */ + handleColumnRemove: function (model, collection) { + // Get position of removed model + var removedPosition = model.get("displayOrder"); + + // Update position values of models + collection.each(function (mod) { + if (mod.get("displayOrder") > removedPosition) { + mod.set("displayOrder", mod.get("displayOrder") - 1, {silent: true}); + } + }); + }, + + /** + * Handler when the column collection is sorted + * @private + */ + handleColumnSort: function() { + // Refresh body + this.grid.body.refresh(); + }, + + /** + * Finds and saves current column header elements + * @private + */ + setHeaderElements: function () { + var self = this; + var rows = self.header.headerRows || [self.header.row]; + self.headerCells = []; + + // Loop all rows + _.each(rows, function (row) { + // Loop cells of row + _.each(row.cells, function (cell) { + var columnModel = self.columns.get({cid: cell.column.cid}); + if (!_.isEmpty(columnModel)) { + self.headerCells.push({ + $el: cell.$el, + el: cell.el, + column: columnModel + }); + } + }); + }); + + // Sort cells + var headerCells = _.sortBy(self.headerCells, function (cell) { + return self.columns.indexOf(cell.column); + }); + + // Filter cells + self.headerCells = _.filter(headerCells, function (cell) { + return cell.column.get("renderable") === true || + typeof cell.column.get("renderable") === "undefined" + }); + + self.headerElements = _.map(self.headerCells, function (cell) { + return cell.el; + }); + }, + + /** + * Adds a drag hook + * @param {String} id + * @param {Function} hook + */ + addDragHook: function (id, hook) { + this.dragHooks[id] = hook; + }, + + /** + * Removes a drag hook + * @param {String} id + */ + removeDragHook: function (id) { + if (this.dragHooks.hasOwnProperty(id)) { + delete this.dragHooks[id]; + } + }, + + /** + * Invokes a drag hook + * @param {String} key + * @private + */ + dragHookInvoke: function (key) { + var args = [].slice.apply(arguments); + args.shift(); + _.each(this.dragHooks, function (obj) { + if (typeof obj[key] == "function") { + obj[key].apply(obj, args); + } + }); + }, + + /** + * Checks whether the ordering should be prevented + * @returns {boolean} + * @private + */ + dragHookPreventOrder: function () { + var prevent = false; + _.each(this.dragHooks, function (obj) { + if (typeof obj.preventOrder == "function") { + prevent |= obj.preventOrder(); + } + }); + return prevent; + }, + + /** + * Helper function to stop event propagation + * @param e + * @private + */ + _stopEvent: function (e) { + if (e.stopPropagation) { + e.stopPropagation(); + } + if (e.preventDefault) { + e.preventDefault(); + } + e.cancelBubble = true; + e.returnValue = false; + }, + + /** + * Use Backbone Events listenTo/stopListening with any DOM element + * + * @param {DOM Element} + * @return {Backbone Events style object} + **/ + _asEvents: function(el) { + var args; + return { + on: function(event, handler) { + if (args) throw new Error("this is one off wrapper"); + el.addEventListener(event, handler, false); + args = [event, handler]; + }, + off: function() { + el.removeEventListener.apply(el, args); + } + }; + } + }); + + /** + * Extendable + * @type {Function} + */ + var orderableDragHook = Backgrid.Extension.OrderableDragHook = function () { + this.initialize.apply(this, arguments); + }; + + /** + * Prototype for the drag hook + */ + _.extend(orderableDragHook.prototype, { + initialize: function () { + }, + dragStart: function () { + }, + dragMove: function () { + }, + dragEnd: function () { + }, + preventOrder: function () { + } + }); + + /** + * Sample collection for orderable columns + */ + Backgrid.Extension.OrderableColumns.orderableColumnCollection = Backgrid.Columns.extend({ + sortKey: "displayOrder", + comparator: function (item) { + return item.get(this.sortKey) || 1e6; + }, + setPositions: function () { + _.each(this.models, function (model, index) { + // If a displayOrder is defined already, do not touch + model.set("displayOrder", model.get("displayOrder") || index + 1, {silent: true}); + }); + return this; + } + }); +})); http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/css/backgrid-sizeable-columns.css ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/css/backgrid-sizeable-columns.css b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/css/backgrid-sizeable-columns.css new file mode 100644 index 0000000..1b4f130 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/css/backgrid-sizeable-columns.css @@ -0,0 +1,35 @@ +/* + backgrid-sizeable-columns + https://github.com/WRidder/backgrid-sizeable-columns + + Copyright (c) 2014 Wilbert van de Ridder + Licensed under the MIT @license. + */ +table.backgrid { + overflow: hidden; + position: relative; +} + +.backgrid .resizeHandler { + width: 16px; + height: 100%; + margin-left: -8px; + top: 0; + position: absolute; + cursor: col-resize; + z-index: 2; +} + +.backgrid .resizeHandler.grid-draggable { + opacity: 1; + width: 1px; + margin-left: 0px; + background-color: #000; +} + +.backgrid .resizeHandler .grid-draggable-cursor { + cursor: col-resize; + width: 100px; + margin-left: -50px; + height: 100%; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/js/backgrid-sizeable-columns.js ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/js/backgrid-sizeable-columns.js b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/js/backgrid-sizeable-columns.js new file mode 100644 index 0000000..2704ca1 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid-sizeable/js/backgrid-sizeable-columns.js @@ -0,0 +1,480 @@ +/* + backgrid-sizeable-columns + https://github.com/WRidder/backgrid-sizeable-columns + + Copyright (c) 2014 Wilbert van de Ridder + Licensed under the MIT @license. + */ +(function (root, factory) { + // CommonJS + if (typeof exports == "object") { + module.exports = factory(require("underscore"), require("backgrid")); + } + // AMD. Register as an anonymous module. + else if (typeof define === 'function' && define.amd) { + define(['underscore', 'backgrid'], factory); + } + // Browser + else { + factory(root._, root.Backgrid); + } + +}(this, function (_, Backgrid) { + "use strict"; + + // Adds width support to columns + Backgrid.Extension.SizeAbleColumns = Backbone.View.extend({ + /** @property */ + tagName: "colgroup", + + /** + * Initializer + * @param options + */ + initialize: function (options) { + this.grid = options.grid; + + // Attach event listeners once on render + this.listenTo(this.grid.header, "backgrid:header:rendered", this.render); + this.listenTo(this.grid.columns, "width:auto", this.setWidthAuto); + this.listenTo(this.grid.columns, "width:fixed", this.setWidthFixed); + this.listenTo(this.grid, "backgrid:refresh", this.setColToActualWidth); + this.listenTo(this.grid.collection, "add remove reset", this.setColToActualWidth); + }, + + /** + * Adds sizeable columns using <col> elements in a <colgroup> + * @returns {Backgrid.Extension.SizeAbleColumns} + */ + render: function () { + var view = this; + view.$el.empty(); + + view.grid.columns.each(function (col) { + if (typeof col.get("renderable") == "undefined" || col.get("renderable")) { + var $colEl = $("<col>").appendTo(view.$el).attr("data-column-cid", col.cid); + var colWidth = col.get("width"); + var colMinWidth = col.get("minWidth"); + var colMaxWidth = col.get("maxWidth"); + if (colWidth && colWidth != "*") { + if (colMinWidth && colWidth < colMinWidth) { + colWidth = colMinWidth; + } + if (colMaxWidth && colWidth > colMaxWidth) { + colWidth = colMaxWidth; + } + $colEl.width(colWidth); + } + } + }); + + // Add data attribute to column cells + if (view.grid.header.headerRows) { + _.each(view.grid.header.headerRows, function(row) { + _.each(row.cells, function(cell) { + cell.$el.attr("data-column-cid", cell.column.cid); + }); + }); + } + else { + _.each(view.grid.header.row.cells, function(cell) { + cell.$el.attr("data-column-cid", cell.column.cid); + }); + } + + // Trigger event + view.grid.collection.trigger("backgrid:colgroup:changed"); + return this; + }, + + /** + * Gets a <col> element belonging to given model + * @param colModel Backgrid.Column + * @returns {*|JQuery|any|jQuery} + * @private + */ + getColumnElement: function (colModel) { + return this.$el.find('col[data-column-cid="' + colModel.cid + '"]'); + }, + + /** + * Get the column width of given model + * @param colModel Backgrid.Column + * @returns {Integer} + * @private + */ + getHeaderElementWidth: function(colModel) { + return this.grid.header.$el.find("th[data-column-cid='" + colModel.cid + "']").outerWidth(); + }, + + /** + * Sets a width of the given column to "*" (auto) + * @param colModel Backgrid.Column + * @private + */ + setWidthAuto: function (colModel) { + // Get column element + var $colElement = this.getColumnElement(colModel); + + // Save width + colModel.set("width", "*"); + + // Set column width to auto + $colElement.css("width", ""); + + view.grid.collection.trigger("backgrid:colgroup:updated"); + }, + + /** + * Sets a width of the given column to a fixed width defined in the model. + * @param colModel Backgrid.Column + * @private + */ + setWidthFixed: function (colModel) { + // Get column element + var $colElement = this.getColumnElement(colModel); + + // Get width of header element + var width = this.getHeaderElementWidth(colModel); + + // Set column width to the original width + $colElement.css("width", width); + + // Save width + colModel.set("width", width); + + view.grid.collection.trigger("backgrid:colgroup:updated"); + }, + + /** + * Updates the view's <col> elements to current width + * @private + */ + setColToActualWidth: function() { + var view = this; + var changed = false; + _.each(view.grid.header.row.cells, function(cell) { + var $colEl = view.getColumnElement(cell.column); + if (cell.column.get("width") !== "*") { + changed = changed || $colEl.width() == cell.$el.outerWidth(); + $colEl.width(cell.$el.outerWidth()); + } + }); + + if (changed) { + view.grid.collection.trigger("backgrid:colgroup:updated"); + } + } + }); + + // Makes column resizable; requires Backgrid.Extension.sizeAbleColumns + Backgrid.Extension.SizeAbleColumnsHandlers = Backbone.View.extend({ + + /** + * Initializer + * @param options + */ + initialize: function (options) { + this.sizeAbleColumns = options.sizeAbleColumns; + this.grid = this.sizeAbleColumns.grid; + this.columns = this.grid.columns; + this.header = this.grid.header; + + this.saveColumnWidth = options.saveColumnWidth; + this.setHeaderElements(); + this.attachEvents(); + }, + + /** + * Adds handlers to resize the columns + * @returns {Backgrid.Extension.SizeAbleColumnsHandlers} + */ + render: function () { + var view = this; + view.$el.empty(); + + // For now, loop tds in first row + _.each(view.headerElements, function (columnEl, index) { + // Get matching col element + var $column = $(columnEl); + var columnModelCid = $column.data("column-cid"); + var $col = view.sizeAbleColumns.$el.find("col[data-column-cid=" + columnModelCid + "]"); + var columnModel = view.columns.get({ cid: columnModelCid}); + + if (columnModel && columnModel.get("resizeable")) { + // Create helper elements + var $resizeHandler = $("<div></div>") + .addClass("resizeHandler") + .attr("data-column-index", index) + .appendTo(view.$el); + var $resizeHandlerHelper = $("<div></div>") + .hide() + .addClass("grid-draggable-cursor") + .appendTo($resizeHandler); + + // Make draggable + $resizeHandler.on("mousedown", function (e) { + view._stopEvent(e); + var startX = Math.round($resizeHandler.offset().left); + var $doc = $(document); + var handlerNonDragSize = $resizeHandler.outerWidth(); + + // Set class + $resizeHandler.addClass("grid-draggable"); + $resizeHandlerHelper.show(); + + // Follow the mouse + var mouseMoveHandler = function (evt) { + view._stopEvent(evt); + + // Check for constraints + var minWidth = columnModel.get("minWidth"); + if (!minWidth || minWidth < 20) { + minWidth = 20; + } + var maxWidth = columnModel.get("maxWidth"); + var newLeftPos = evt.pageX; + var currentWidth = columnModel.get("width"); + var newWidth = currentWidth + (newLeftPos - startX) - handlerNonDragSize / 2; + + if (minWidth && newWidth <= minWidth) { + newLeftPos = startX - (currentWidth - minWidth) + handlerNonDragSize / 2; + } + if (maxWidth && newWidth >= maxWidth) { + newLeftPos = startX + maxWidth - currentWidth + handlerNonDragSize / 2; + } + + // Apply mouse change to handler + $resizeHandler.offset({ + left: newLeftPos + }); + }; + $doc.on("mousemove", mouseMoveHandler); + + // Add handler to listen for mouseup + var mouseUpHandler = function (evt) { + // Cleanup + view._stopEvent(evt); + $resizeHandler.removeClass("grid-draggable"); + $resizeHandlerHelper.hide(); + $doc.off("mouseup", mouseUpHandler); + $doc.off("mousemove", mouseMoveHandler); + + // Adjust column size + var stopX = Math.round($resizeHandler.offset().left); + var offset = (startX - stopX); + var oldWidth = $column.outerWidth(); + var newWidth = oldWidth - offset; + $col.width(newWidth); + + // Get actual width + var finalWidth = $column.outerWidth(); + $col.width(finalWidth); + + // Save width and trigger events + if (finalWidth != oldWidth) { + if (view.saveColumnWidth) { + // Save updated width + columnModel.set("width", finalWidth, {silent: true}); + } + + // Trigger event + columnModel.trigger("resize", columnModel, finalWidth, oldWidth); + + // Check if we have an autosize column, if so, trigger resize on it as well + var autoWidthColumn = view.columns.findWhere({ + width: "*" + }); + if (autoWidthColumn) { + autoWidthColumn.trigger("resize", autoWidthColumn); + } + } + view.updateHandlerPosition(); + }; + $doc.on("mouseup", mouseUpHandler); + }); + } + }); + + // Position drag handlers + view.updateHandlerPosition(); + + return this; + }, + /** + * Helper function to prevent event propagation + * @param e {Event} + * @private + */ + _stopEvent: function (e) { + if (e.stopPropagation) { + e.stopPropagation(); + } + if (e.preventDefault) { + e.preventDefault(); + } + e.cancelBubble = true; + e.returnValue = false; + }, + + /** + * Add listeners + * @private + */ + attachEvents: function () { + var view = this; + view.listenTo(view.columns, "change:resizeable", view.render); + view.listenTo(view.columns, "resize width:auto width:fixed add remove", view.checkSpacerColumn); + view.listenTo(view.grid.collection, "backgrid:colgroup:updated", view.updateHandlerPosition); + view.listenTo(view.grid.collection, "backgrid:colgroup:changed", function () { + // Wait for callstack to be cleared + _.defer(function () { + view.setHeaderElements(); + view.render(); + }); + }); + + var resizeEvtHandler = _.debounce(_.bind(view.updateHandlerPosition, view), 250); + view.listenTo(view._asEvents(window), "resize", resizeEvtHandler); + }, + + /** + * Checks whether a spacer column is nessecary. This is the case when widths are set on all columns and it's smaller + * that the grid element width. + * @private + */ + checkSpacerColumn: function () { + var view = this; + var spacerColumn = _.first(view.columns.where({name: "__spacerColumn"})); + var autoColumns = view.columns.filter(function (col) { + return col.get("width") == "*" && col.get("name") != "__spacerColumn"; + }); + + // Check if there is a column with auto width, if so, no need to do anything + if (_.isEmpty(autoColumns)) { + var totalWidth = view.columns.reduce(function (memo, num) { + var colWidth = (num.get("width") == "*") ? 0 : num.get("width"); + return memo + colWidth; + }, 0); + var gridWidth = view.grid.$el.width(); + + if (gridWidth > totalWidth) { + // The grid is larger than the cumulative column width, we need a spacer column + if (!spacerColumn) { + // Create new column model + view.columns.add(view.getSpacerColumn()); + } + } + else { + // Cumulative column width exceeds grid width, no need for a spacerColumn. + if (spacerColumn) { + view.columns.remove(spacerColumn); + } + } + } + else if (spacerColumn) { + view.columns.remove(spacerColumn); + } + }, + + /** + * Returns a spacer column definition + * @returns Object + * @private + */ + getSpacerColumn: function() { + return Backgrid.Extension.SizeAbleColumns.spacerColumnDefinition; + }, + + /** + * Updates the position of the handlers + * @private + */ + updateHandlerPosition: function () { + var view = this; + _.each(view.headerElements, function (columnEl, index) { + var $column = $(columnEl); + + // Get handler for current column and update position + view.$el.children().filter("[data-column-index='" + index + "']") + .css("left", $column.position().left + $column.outerWidth()); + }); + }, + + /** + * Find the current header elements and stores them + */ + setHeaderElements: function () { + var self = this; + var rows = self.grid.header.headerRows || [self.grid.header.row]; + self.headerCells = []; + + // Loop all rows + _.each(rows, function (row) { + // Loop cells of row + _.each(row.cells, function (cell) { + var columnModel = self.columns.get({cid: cell.column.cid}); + if (!_.isEmpty(columnModel)) { + self.headerCells.push({ + $el: cell.$el, + el: cell.el, + column: columnModel + }); + } + }); + }); + + // Sort cells + var headerCells = _.sortBy(self.headerCells, function (cell) { + return self.columns.indexOf(cell.column); + }); + + // Filter cells + self.headerCells = _.filter(headerCells, function(cell) { + return cell.column.get("renderable") === true || + typeof cell.column.get("renderable") === "undefined" + }); + + self.headerElements = _.map(self.headerCells, function (cell) { + return cell.el; + }); + }, + + /** + * Use Backbone Events listenTo/stopListening with any DOM element + * + * @param {DOM Element} + * @return {Backbone Events style object} + **/ + _asEvents: function(el) { + var args; + return { + on: function(event, handler) { + if (args) throw new Error("this is one off wrapper"); + el.addEventListener(event, handler, false); + args = [event, handler]; + }, + off: function() { + el.removeEventListener.apply(el, args); + } + }; + } + }); + + /** + * Sample definition for the spacer column + */ + Backgrid.Extension.SizeAbleColumns.spacerColumnDefinition = { + name: "__spacerColumn", + label: "", + editable: false, + cell: Backgrid.StringCell, + width: "*", + nesting: [], + resizeable: false, + sortable: false, + orderable: false, + displayOrder: 9999 + }; + return Backgrid; +})); http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.css ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.css b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.css new file mode 100644 index 0000000..da7b4a4 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.css @@ -0,0 +1,240 @@ +/* + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. +*/ + +.backgrid-container { + position: relative; + display: block; + width: 100%; + height: 465px; + padding: 0; + overflow: auto; + border: 0; +} + +.backgrid { + width: 100%; + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.backgrid th, +.backgrid td { + display: none; + height: 20px; + max-width: 250px; + padding: 4px 5px; + /*overflow: hidden;*/ + line-height: 20px; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; + vertical-align: middle; + border-bottom: 1px solid #DDD; +} + +.backgrid th.renderable, +.backgrid td.renderable { + display: table-cell; +} + +.backgrid th { + font-weight: bold; + text-align: center; +} + +.backgrid th.sortable a { + text-decoration: none; + white-space: nowrap; + cursor: pointer; +} + +.backgrid thead th { + vertical-align: bottom; + background-color: #f9f9f9; +} + +.backgrid thead th a { + display: block; +} + +.backgrid.backgrid-striped tbody tr:nth-child(even) { + background-color: #f9f9f9; +} + +.backgrid tbody tr.empty { + font-style: italic; + color: gray; +} + +.backgrid tbody tr.empty td { + display: inherit; + text-align: center; +} + +.backgrid td.editor { + padding: 0; +} + +.backgrid td.editor, +.backgrid tbody tr:nth-child(odd) td.editor { + background-color: rgba(82, 168, 236, 0.1); + outline: 1px solid rgba(82, 168, 236, 0.8); + outline-offset: -1px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition-duration: 200ms; + -moz-transition-duration: 200ms; + -o-transition-duration: 200ms; + transition-duration: 200ms; + -webkit-transition-property: width, outline, background-color; + -moz-transition-property: width, outline, background-color; + -o-transition-property: width, outline, background-color; + transition-property: width, outline, background-color; + -webkit-transition-timing-function: ease-in-out; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; +} + +.backgrid td.editor input[type=text] { + display: block; + width: 100%; + height: 100%; + padding: 0 5px; + margin: 0; + background-color: transparent; + border: 0; + outline: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; +} + +.backgrid td.editor input[type=text]::-ms-clear { + display: none; +} + +.backgrid td.error, +.backgrid tbody tr:nth-child(odd) td.error { + background-color: rgba(255, 210, 77, 0.1); + outline: 1px solid #ffd24d; +} + +.backgrid td.editor :focus, +.backgrid th.editor :focus { + outline: 0; +} + +.backgrid .sort-caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.3em; + border: 0; + content: ""; +} + +.backgrid .ascending .sort-caret { + vertical-align: baseline; + border-top: none; + border-right: 4px solid transparent; + border-bottom: 4px solid #000000; + border-left: 4px solid transparent; +} + +.backgrid .descending .sort-caret { + vertical-align: super; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-bottom: none; + border-left: 4px solid transparent; +} + +.backgrid .string-cell, +.backgrid .uri-cell, +.backgrid .email-cell, +.backgrid .string-cell.editor input[type=text], +.backgrid .uri-cell.editor input[type=text], +.backgrid .email-cell.editor input[type=text] { + text-align: left; +} + +.backgrid .date-cell, +.backgrid .time-cell, +.backgrid .datetime-cell, +.backgrid .number-cell, +.backgrid .integer-cell, +.backgrid .percent-cell, +.backgrid .date-cell.editor input[type=text], +.backgrid .time-cell.editor input[type=text], +.backgrid .datetime-cell.editor input[type=text], +.backgrid .number-cell.editor input[type=text], +.backgrid .integer-cell.editor input[type=text], +.backgrid .percent-cell.editor input[type=text] { + text-align: right; +} + +.backgrid .boolean-cell, +.backgrid .boolean-cell.editor input[type=checkbox] { + text-align: center; +} + +.backgrid .select-cell { + text-align: center; +} + +.backgrid .select-cell.editor { + padding: 0; +} + +.backgrid .select-cell.editor select { + display: block; + width: 100%; + height: 28px; + padding: 4px 5px; + margin: 0; + line-height: 28px; + vertical-align: middle; + background-color: white; + border: 0; + outline: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.backgrid .select-cell.editor select[multiple] { + height: auto; +} + +.backgrid .select-cell.editor :focus { + border: 0; + outline: 0; +} + +.backgrid .select-cell.editor select::-moz-focus-inner, +.backgrid .select-cell.editor optgroup::-moz-focus-inner, +.backgrid .select-cell.editor option::-moz-focus-inner, +.backgrid .select-cell.editor select::-o-focus-inner, +.backgrid .select-cell.editor optgroup::-o-focus-inner, +.backgrid .select-cell.editor option::-o-focus-inner { + border: 0; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/39c85bb8/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.min.css ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.min.css b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.min.css new file mode 100644 index 0000000..764e799 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-portal/src/main/webapp/libs/bower/backgrid/css/backgrid.min.css @@ -0,0 +1 @@ +.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{display:none;height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;border-bottom:1px solid #DDD}.backgrid th.renderable,.backgrid td.renderable{display:table-cell}.backgrid th{font-weight:bold;text-align:center}.backgrid th.sortable a{text-decoration:none;white-space:nowrap;cursor:pointer}.backgrid thead th{vertical-align:bottom;background-color:#f9f9f9}.backgrid thead th a{display:block}.backgrid.backgrid-striped tbody tr:nth-child(even){background-color:#f9f9f9}.backgrid tbody tr.empty{font-style:italic;color:gray}.backgrid tbody tr.empty td{display:inherit;text-align:center}.backgrid td.edito r{padding:0}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0 5px;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-b ox;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.editor input[type=text]::-ms-clear{display:none}.backgrid td.error,.backgrid tbody tr:nth-child(odd) td.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}. backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .percent-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text],.backgrid .percent-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor select[multiple]{height:auto}.backgr id .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0} \ No newline at end of file
