diff --git a/UI/.idea/runConfigurations/Debug___Chrome.xml b/UI/.idea/runConfigurations/Debug___Chrome.xml
index 4ad681dfa..2323f096d 100644
--- a/UI/.idea/runConfigurations/Debug___Chrome.xml
+++ b/UI/.idea/runConfigurations/Debug___Chrome.xml
@@ -3,22 +3,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UI/.idea/runConfigurations/Debug___Firefox.xml b/UI/.idea/runConfigurations/Debug___Firefox.xml
index 599880f12..1f0cbd78b 100644
--- a/UI/.idea/runConfigurations/Debug___Firefox.xml
+++ b/UI/.idea/runConfigurations/Debug___Firefox.xml
@@ -3,22 +3,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UI/Cells/AirDateCell.js b/UI/Cells/AirDateCell.js
index 702afbb7c..c6a0b3ebe 100644
--- a/UI/Cells/AirDateCell.js
+++ b/UI/Cells/AirDateCell.js
@@ -1,5 +1,5 @@
"use strict";
-define(['app', 'Shared/FormatHelpers'], function () {
+define(['app', 'Shared/FormatHelpers','backgrid'], function () {
NzbDrone.Cells.AirDateCell = Backgrid.Cell.extend({
className: "air-date-cell",
diff --git a/UI/History/HistoryLayout.js b/UI/History/HistoryLayout.js
index 079b04367..f739cc02c 100644
--- a/UI/History/HistoryLayout.js
+++ b/UI/History/HistoryLayout.js
@@ -10,6 +10,8 @@ define([
'Cells/EpisodeTitleCell',
'Cells/QualityCell',
'Shared/Toolbar/ToolbarLayout',
+ 'Shared/Grid/Pager',
+ 'Shared/Grid/HeaderCell',
'Shared/LoadingView'
],
function () {
@@ -67,7 +69,7 @@ define([
className : 'table table-hover'
}));
- this.pager.show(new Backgrid.NzbDronePaginator({
+ this.pager.show(new NzbDrone.Shared.Grid.Pager({
columns : this.columns,
collection: this.historyCollection
}));
diff --git a/UI/Index.html b/UI/Index.html
index fe6654452..9b736d495 100644
--- a/UI/Index.html
+++ b/UI/Index.html
@@ -93,9 +93,8 @@
-
-
-
+
@@ -106,7 +105,6 @@
-
diff --git a/UI/Logs/Layout.js b/UI/Logs/Layout.js
index 185ee225b..00da82270 100644
--- a/UI/Logs/Layout.js
+++ b/UI/Logs/Layout.js
@@ -2,7 +2,8 @@
define([
'app',
'Logs/Collection',
- 'Shared/Toolbar/ToolbarLayout'
+ 'Shared/Toolbar/ToolbarLayout',
+ 'Shared/Grid/Pager'
],
function () {
NzbDrone.Logs.Layout = Backbone.Marionette.Layout.extend({
@@ -50,7 +51,7 @@ define([
className : 'table table-hover'
}));
- this.pager.show(new Backgrid.NzbDronePaginator({
+ this.pager.show(new NzbDrone.Shared.Grid.Pager({
columns : this.columns,
collection: this.collection
}));
diff --git a/UI/Missing/MissingLayout.js b/UI/Missing/MissingLayout.js
index fdd4e32d8..29c0f06e1 100644
--- a/UI/Missing/MissingLayout.js
+++ b/UI/Missing/MissingLayout.js
@@ -10,6 +10,7 @@ define([
'Cells/EpisodeNumberCell',
'Cells/EpisodeTitleCell',
'Cells/AirDateCell',
+ 'Shared/Grid/Pager',
'Shared/LoadingView'
],
function () {
@@ -57,7 +58,7 @@ define([
className : 'table table-hover'
}));
- this.pager.show(new Backgrid.NzbDronePaginator({
+ this.pager.show(new NzbDrone.Shared.Grid.Pager({
columns : this.columns,
collection: this.missingCollection
}));
diff --git a/UI/Mixins/backbone.Backgrid.mixin.js b/UI/Mixins/backbone.Backgrid.mixin.js
deleted file mode 100644
index fe3572a42..000000000
--- a/UI/Mixins/backbone.Backgrid.mixin.js
+++ /dev/null
@@ -1,243 +0,0 @@
-"use strict";
-
-Backgrid.Column.prototype.defaults = {
- name : undefined,
- label : undefined,
- sortable : true,
- editable : false,
- renderable: true,
- formatter : undefined,
- cell : undefined,
- headerCell: 'nzbDrone'
-};
-
-
-Backgrid.NzbDroneHeaderCell = Backgrid.HeaderCell.extend({
- events: {
- 'click': 'onClick'
- },
-
- render: function () {
- this.$el.empty();
- this.$el.append(this.column.get("label"));
-
- if (this.column.get('sortable')) {
- this.$el.addClass('clickable');
- this.$el.append(" ");
-
- if (this.collection.state) {
- var sortKey = this.collection.state.sortKey;
- var sortDir = this._convertIntToDirection(this.collection.state.order);
-
- if (sortKey === this.column.get('name')) {
- this.$el.children('i').addClass(this._convertDirectionToIcon(sortDir));
- this._direction = sortDir;
- }
- }
- }
- this.delegateEvents();
- return this;
- },
-
- direction: function (dir) {
- if (arguments.length) {
- if (this._direction) {
- this.$el.children('i').removeClass(this._convertDirectionToIcon(this._direction));
- }
- if (dir) {
- this.$el.children('i').addClass(this._convertDirectionToIcon(dir));
- }
- this._direction = dir;
- }
-
- return this._direction;
- },
-
- onClick: function (e) {
- e.preventDefault();
-
- var columnName = this.column.get("name");
-
- if (this.column.get("sortable")) {
- if (this.direction() === "ascending") {
- this.sort(columnName, "descending", function (left, right) {
- var leftVal = left.get(columnName);
- var rightVal = right.get(columnName);
- if (leftVal === rightVal) {
- return 0;
- }
- else if (leftVal > rightVal) {
- return -1;
- }
- return 1;
- });
- }
- else {
- this.sort(columnName, "ascending", function (left, right) {
- var leftVal = left.get(columnName);
- var rightVal = right.get(columnName);
- if (leftVal === rightVal) {
- return 0;
- }
- else if (leftVal < rightVal) {
- return -1;
- }
- return 1;
- });
- }
- }
- },
-
- _convertDirectionToIcon: function (dir) {
- if (dir === 'ascending') {
- return 'icon-sort-up';
- }
-
- return 'icon-sort-down';
- },
-
- _convertIntToDirection: function (dir) {
- if (dir === '-1') {
- return 'ascending';
- }
-
- return 'descending';
- }
-});
-
-Backgrid.NzbDronePaginator = Backgrid.Extension.Paginator.extend({
-
- template: 'Shared/BackgridPaginatorTemplate',
-
- events: {
- "click .pager-btn": "changePage"
- },
-
- windowSize: 1,
-
- fastForwardHandleLabels: {
- first: 'icon-fast-backward',
- prev : 'icon-backward',
- next : 'icon-forward',
- last : 'icon-fast-forward'
- },
-
- changePage: function (e) {
- e.preventDefault();
-
- var target = $(e.target);
-
- if (target.closest('li').hasClass('disabled')) {
- return;
- }
-
- var label = target.attr('data-action');
- var ffLabels = this.fastForwardHandleLabels;
-
- var collection = this.collection;
-
- if (ffLabels) {
- switch (label) {
- case 'first':
- collection.getFirstPage();
- return;
- case 'prev':
- if (collection.hasPrevious()) {
- collection.getPreviousPage();
- }
- return;
- case 'next':
- if (collection.hasNext()) {
- collection.getNextPage();
- }
- return;
- case 'last':
- collection.getLastPage();
- return;
- }
- }
-
- var state = collection.state;
- var pageIndex = $(e.target).text() * 1;
- collection.getPage(state.firstPage === 0 ? pageIndex - 1 :pageIndex);
- },
-
- makeHandles: function () {
-
- var handles = [];
- 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 windowStart = Math.floor(currentPage / this.windowSize) * this.windowSize;
- var windowEnd = Math.min(lastPage + 1, windowStart + this.windowSize);
-
- if (collection.mode !== "infinite") {
- for (var i = windowStart; i < windowEnd; i++) {
- handles.push({
- label: i + 1,
- title: "No. " + (i + 1),
- className: currentPage === i ? "active" : undefined,
- pageNumber: i + 1
- });
- }
- }
-
- var ffLabels = this.fastForwardHandleLabels;
- if (ffLabels) {
-
- if (ffLabels.prev) {
- handles.unshift({
- label: ffLabels.prev,
- className: collection.hasPrevious() ? void 0 : "disabled",
- action: 'prev'
- });
- }
-
- if (ffLabels.first) {
- handles.unshift({
- label: ffLabels.first,
- className: collection.hasPrevious() ? void 0 : "disabled",
- action: 'first'
- });
- }
-
- if (ffLabels.next) {
- handles.push({
- label: ffLabels.next,
- className: collection.hasNext() ? void 0 : "disabled",
- action: 'next'
- });
- }
-
- if (ffLabels.last) {
- handles.push({
- label: ffLabels.last,
- className: collection.hasNext() ? void 0 : "disabled",
- action: 'last'
- });
- }
- }
-
- return handles;
- },
-
- render: function () {
- this.$el.empty();
-
- var templateFunction = Marionette.TemplateCache.get(this.template);
-
- this.$el.html(templateFunction({
- handles: this.makeHandles()
- }));
-
- this.delegateEvents();
-
- return this;
- }
-});
diff --git a/UI/Release/ApprovalStatusCell.js b/UI/Release/ApprovalStatusCell.js
index b5662bdb6..20ca112f8 100644
--- a/UI/Release/ApprovalStatusCell.js
+++ b/UI/Release/ApprovalStatusCell.js
@@ -1,19 +1,22 @@
"use strict";
-NzbDrone.Release.ApprovalStatusCell = Backgrid.Cell.extend({
- className: "approval-status-cell",
+require(['app', 'backgrid'], function () {
+ NzbDrone.Release.ApprovalStatusCell = Backgrid.Cell.extend({
- render: function () {
- var rejections = this.model.get(this.column.get("name"));
+ className: "approval-status-cell",
- var result = '';
+ render: function () {
+ var rejections = this.model.get(this.column.get("name"));
- _.each(rejections, function (reason) {
- result += reason + ' ';
- });
+ var result = '';
- this.$el.html(result);
- this.delegateEvents();
- return this;
- }
+ _.each(rejections, function (reason) {
+ result += reason + ' ';
+ });
+
+ this.$el.html(result);
+ this.delegateEvents();
+ return this;
+ }
+ });
});
diff --git a/UI/Shared/Grid/HeaderCell.js b/UI/Shared/Grid/HeaderCell.js
new file mode 100644
index 000000000..27e9b88f5
--- /dev/null
+++ b/UI/Shared/Grid/HeaderCell.js
@@ -0,0 +1,106 @@
+"use strict";
+
+Backgrid.Column.prototype.defaults = {
+ name : undefined,
+ label : undefined,
+ sortable : true,
+ editable : false,
+ renderable: true,
+ formatter : undefined,
+ cell : undefined,
+ headerCell: 'nzbDrone'
+};
+
+
+Backgrid.NzbDroneHeaderCell = Backgrid.HeaderCell.extend({
+ events: {
+ 'click': 'onClick'
+ },
+
+ render: function () {
+ this.$el.empty();
+ this.$el.append(this.column.get("label"));
+
+ if (this.column.get('sortable')) {
+ this.$el.addClass('clickable');
+ this.$el.append(" ");
+
+ if (this.collection.state) {
+ var sortKey = this.collection.state.sortKey;
+ var sortDir = this._convertIntToDirection(this.collection.state.order);
+
+ if (sortKey === this.column.get('name')) {
+ this.$el.children('i').addClass(this._convertDirectionToIcon(sortDir));
+ this._direction = sortDir;
+ }
+ }
+ }
+ this.delegateEvents();
+ return this;
+ },
+
+ direction: function (dir) {
+ if (arguments.length) {
+ if (this._direction) {
+ this.$el.children('i').removeClass(this._convertDirectionToIcon(this._direction));
+ }
+ if (dir) {
+ this.$el.children('i').addClass(this._convertDirectionToIcon(dir));
+ }
+ this._direction = dir;
+ }
+
+ return this._direction;
+ },
+
+ onClick: function (e) {
+ e.preventDefault();
+
+ var columnName = this.column.get("name");
+
+ if (this.column.get("sortable")) {
+ if (this.direction() === "ascending") {
+ this.sort(columnName, "descending", function (left, right) {
+ var leftVal = left.get(columnName);
+ var rightVal = right.get(columnName);
+ if (leftVal === rightVal) {
+ return 0;
+ }
+ else if (leftVal > rightVal) {
+ return -1;
+ }
+ return 1;
+ });
+ }
+ else {
+ this.sort(columnName, "ascending", function (left, right) {
+ var leftVal = left.get(columnName);
+ var rightVal = right.get(columnName);
+ if (leftVal === rightVal) {
+ return 0;
+ }
+ else if (leftVal < rightVal) {
+ return -1;
+ }
+ return 1;
+ });
+ }
+ }
+ },
+
+ _convertDirectionToIcon: function (dir) {
+ if (dir === 'ascending') {
+ return 'icon-sort-up';
+ }
+
+ return 'icon-sort-down';
+ },
+
+ _convertIntToDirection: function (dir) {
+ if (dir === '-1') {
+ return 'ascending';
+ }
+
+ return 'descending';
+ }
+});
diff --git a/UI/Shared/Grid/Pager.js b/UI/Shared/Grid/Pager.js
new file mode 100644
index 000000000..357703a43
--- /dev/null
+++ b/UI/Shared/Grid/Pager.js
@@ -0,0 +1,156 @@
+"use strict";
+
+Backgrid.Column.prototype.defaults = {
+ name : undefined,
+ label : undefined,
+ sortable : true,
+ editable : false,
+ renderable: true,
+ formatter : undefined,
+ cell : undefined,
+ headerCell: 'nzbDrone'
+};
+
+
+define([
+ 'app',
+ 'JsLibraries/backbone.backgrid.paginator'
+], function () {
+
+ NzbDrone.Shared.Grid.Pager = Backgrid.Extension.Paginator.extend({
+
+ template: 'Shared/Grid/PagerTemplate',
+
+ events: {
+ "click .pager-btn": "changePage"
+ },
+
+ windowSize: 1,
+
+ fastForwardHandleLabels: {
+ first: 'icon-fast-backward',
+ prev : 'icon-backward',
+ next : 'icon-forward',
+ last : 'icon-fast-forward'
+ },
+
+ changePage: function (e) {
+ e.preventDefault();
+
+ var target = $(e.target);
+
+ if (target.closest('li').hasClass('disabled')) {
+ return;
+ }
+
+ var label = target.attr('data-action');
+ var ffLabels = this.fastForwardHandleLabels;
+
+ var collection = this.collection;
+
+ if (ffLabels) {
+ switch (label) {
+ case 'first':
+ collection.getFirstPage();
+ return;
+ case 'prev':
+ if (collection.hasPrevious()) {
+ collection.getPreviousPage();
+ }
+ return;
+ case 'next':
+ if (collection.hasNext()) {
+ collection.getNextPage();
+ }
+ return;
+ case 'last':
+ collection.getLastPage();
+ return;
+ }
+ }
+
+ var state = collection.state;
+ var pageIndex = $(e.target).text() * 1;
+ collection.getPage(state.firstPage === 0 ? pageIndex - 1 :pageIndex);
+ },
+
+ makeHandles: function () {
+
+ var handles = [];
+ 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 windowStart = Math.floor(currentPage / this.windowSize) * this.windowSize;
+ var windowEnd = Math.min(lastPage + 1, windowStart + this.windowSize);
+
+ if (collection.mode !== "infinite") {
+ for (var i = windowStart; i < windowEnd; i++) {
+ handles.push({
+ label : i + 1,
+ title : "No. " + (i + 1),
+ className : currentPage === i ? "active" :undefined,
+ pageNumber: i + 1
+ });
+ }
+ }
+
+ var ffLabels = this.fastForwardHandleLabels;
+ if (ffLabels) {
+
+ if (ffLabels.prev) {
+ handles.unshift({
+ label : ffLabels.prev,
+ className: collection.hasPrevious() ? void 0 :"disabled",
+ action : 'prev'
+ });
+ }
+
+ if (ffLabels.first) {
+ handles.unshift({
+ label : ffLabels.first,
+ className: collection.hasPrevious() ? void 0 :"disabled",
+ action : 'first'
+ });
+ }
+
+ if (ffLabels.next) {
+ handles.push({
+ label : ffLabels.next,
+ className: collection.hasNext() ? void 0 :"disabled",
+ action : 'next'
+ });
+ }
+
+ if (ffLabels.last) {
+ handles.push({
+ label : ffLabels.last,
+ className: collection.hasNext() ? void 0 :"disabled",
+ action : 'last'
+ });
+ }
+ }
+
+ return handles;
+ },
+
+ render: function () {
+ this.$el.empty();
+
+ var templateFunction = Marionette.TemplateCache.get(this.template);
+
+ this.$el.html(templateFunction({
+ handles: this.makeHandles()
+ }));
+
+ this.delegateEvents();
+
+ return this;
+ }
+ });
+});
diff --git a/UI/Shared/BackgridPaginatorTemplate.html b/UI/Shared/Grid/PagerTemplate.html
similarity index 100%
rename from UI/Shared/BackgridPaginatorTemplate.html
rename to UI/Shared/Grid/PagerTemplate.html
diff --git a/UI/app.js b/UI/app.js
index 434a43268..a50b06210 100644
--- a/UI/app.js
+++ b/UI/app.js
@@ -3,9 +3,11 @@ require.config({
paths: {
'backbone' : 'JsLibraries/backbone',
+ '$' : 'JsLibraries/jquery',
'underscore': 'JsLibraries/underscore',
'marionette': 'JsLibraries/backbone.marionette',
- 'handlebars': 'JsLibraries/handlebars'
+ 'handlebars': 'JsLibraries/handlebars',
+ 'libs' : 'JsLibraries/'
},
shim: {
@@ -13,7 +15,7 @@ require.config({
exports: '_'
},
backbone : {
- deps : ['underscore'],
+ deps : ['underscore', '$'],
exports: 'Backbone'
},
marionette: {
@@ -22,11 +24,19 @@ require.config({
},
handlebars: {
exports: 'Handlebars'
+ },
+
+ backbone_backgrid :{
+ exports: 'backgrid'
+ },
+
+ backgrid : {
+ deps: ['backbone', 'libs/backbone.backgrid', 'libs/backbone.backgrid.paginator']
}
}
});
-define('app', ['shared/modal/region'], function (ModalRegion) {
+define(['backbone','backgrid'], function (ModalRegion) {
window.NzbDrone = new Backbone.Marionette.Application();
window.NzbDrone.Config = {};
@@ -64,7 +74,8 @@ define('app', ['shared/modal/region'], function (ModalRegion) {
window.NzbDrone.Shared = {
Toolbar : {},
Messenger : {},
- FormatHelpers: {}
+ FormatHelpers: {},
+ Grid : {}
};