diff --git a/NzbDrone.Core/Model/HistoryQueryModel.cs b/NzbDrone.Core/Model/HistoryQueryModel.cs
new file mode 100644
index 000000000..00a018c2b
--- /dev/null
+++ b/NzbDrone.Core/Model/HistoryQueryModel.cs
@@ -0,0 +1,26 @@
+using System;
+using NzbDrone.Core.Repository;
+using NzbDrone.Core.Repository.Quality;
+using PetaPoco;
+
+namespace NzbDrone.Core.Model
+{
+ public class HistoryQueryModel
+ {
+ public int HistoryId { get; set; }
+ public int EpisodeId { get; set; }
+ public int SeriesId { get; set; }
+ public string NzbTitle { get; set; }
+ public QualityTypes Quality { get; set; }
+ public DateTime Date { get; set; }
+ public bool IsProper { get; set; }
+ public string Indexer { get; set; }
+ public string NzbInfoUrl { get; set; }
+
+ public string EpisodeTitle { get; set; }
+ public int SeasonNumber { get; set; }
+ public int EpisodeNumber { get; set; }
+ public string EpisodeOverview { get; set; }
+ public string SeriesTitle { get; set; }public int Id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index 7dedf5250..3f7acc5fd 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -123,6 +123,10 @@
+
+ False
+ ..\packages\DataTables.Mvc.Core.0.1.0.85\lib\DataTables.Mvc.Core.dll
+
..\Libraries\DeskMetrics\DeskMetrics.NET.dll
@@ -251,6 +255,7 @@
+
diff --git a/NzbDrone.Core/Providers/HistoryProvider.cs b/NzbDrone.Core/Providers/HistoryProvider.cs
index 94a3c8479..807c39fb6 100644
--- a/NzbDrone.Core/Providers/HistoryProvider.cs
+++ b/NzbDrone.Core/Providers/HistoryProvider.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using DataTables.Mvc.Core.Helpers;
+using DataTables.Mvc.Core.Models;
using Ninject;
using NLog;
using NzbDrone.Core.Model;
@@ -77,5 +79,42 @@ namespace NzbDrone.Core.Providers
{
_database.Delete(historyId);
}
+
+ public virtual Page GetPagedItems(DataTablesPageRequest pageRequest)
+ {
+ var query = Sql.Builder
+ .Select(@"History.*, Series.Title as SeriesTitle, Episodes.Title as EpisodeTitle,
+ Episodes.SeasonNumber as SeasonNumber, Episodes.EpisodeNumber as EpisodeNumber,
+ Episodes.Overview as EpisodeOverview")
+ .From("History")
+ .InnerJoin("Series")
+ .On("History.SeriesId = Series.SeriesId")
+ .InnerJoin("Episodes")
+ .On("History.EpisodeId = Episodes.EpisodeId");
+
+ var startPage = (pageRequest.DisplayLength == 0) ? 1 : pageRequest.DisplayStart / pageRequest.DisplayLength + 1;
+
+ if (!string.IsNullOrEmpty(pageRequest.Search))
+ {
+ var whereClause = string.Join(" OR ", SqlBuilderHelper.GetSearchClause(pageRequest));
+
+ if (!string.IsNullOrEmpty(whereClause))
+ query.Append("WHERE " + whereClause, "%" + pageRequest.Search + "%");
+ }
+
+ var orderBy = string.Join(",", SqlBuilderHelper.GetOrderByClause(pageRequest));
+
+ if (!string.IsNullOrEmpty(orderBy))
+ {
+ query.Append("ORDER BY " + orderBy);
+ }
+
+ return _database.Page(startPage, pageRequest.DisplayLength, query);
+ }
+
+ public virtual long Count()
+ {
+ return _database.Single(@"SELECT COUNT(*) from History");
+ }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config
index 28e5af301..f24ef5601 100644
--- a/NzbDrone.Core/packages.config
+++ b/NzbDrone.Core/packages.config
@@ -1,5 +1,6 @@
+
diff --git a/NzbDrone.Web/App_Start/DataTablesMvc.cs b/NzbDrone.Web/App_Start/DataTablesMvc.cs
index 6ac4a3b4f..8375e53ab 100644
--- a/NzbDrone.Web/App_Start/DataTablesMvc.cs
+++ b/NzbDrone.Web/App_Start/DataTablesMvc.cs
@@ -10,8 +10,8 @@ namespace NzbDrone.Web.App_Start
{
public static void Start()
{
- if (!ModelBinders.Binders.ContainsKey(typeof(DataTablesParams)))
- ModelBinders.Binders.Add(typeof(DataTablesParams), new DataTablesModelBinder());
+ if (!ModelBinders.Binders.ContainsKey(typeof(DataTablesPageRequest)))
+ ModelBinders.Binders.Add(typeof(DataTablesPageRequest), new DataTablesModelBinder());
}
}
}
\ No newline at end of file
diff --git a/NzbDrone.Web/Controllers/HistoryController.cs b/NzbDrone.Web/Controllers/HistoryController.cs
index 06e50b185..4aee08267 100644
--- a/NzbDrone.Web/Controllers/HistoryController.cs
+++ b/NzbDrone.Web/Controllers/HistoryController.cs
@@ -1,6 +1,9 @@
-using System.Linq;
+using System;
+using System.Linq;
+using System.Linq.Dynamic;
using System.Web.Mvc;
using System.Web.Script.Serialization;
+using DataTables.Mvc.Core.Models;
using NzbDrone.Core.Helpers;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Providers;
@@ -24,15 +27,46 @@ namespace NzbDrone.Web.Controllers
return View();
}
- public JsonResult AjaxBinding()
+ //public JsonResult AjaxBinding()
+ //{
+ // var history = _historyProvider.AllItemsWithRelationships().Select(h => new HistoryModel
+ // {
+ // HistoryId = h.HistoryId,
+ // SeriesId = h.SeriesId,
+ // EpisodeNumbering = string.Format("{0}x{1:00}", h.Episode.SeasonNumber, h.Episode.EpisodeNumber),
+ // EpisodeTitle = h.Episode.Title,
+ // EpisodeOverview = h.Episode.Overview,
+ // SeriesTitle = h.SeriesTitle,
+ // SeriesTitleSorter = SortHelper.SkipArticles(h.SeriesTitle),
+ // NzbTitle = h.NzbTitle,
+ // Quality = h.Quality.ToString(),
+ // IsProper = h.IsProper,
+ // Date = h.Date.ToString(),
+ // DateSorter = h.Date.ToString("MM/dd/yyyy h:mm:ss tt"),
+ // Indexer = h.Indexer,
+ // EpisodeId = h.EpisodeId,
+ // NzbInfoUrl = h.NzbInfoUrl
+ // }).OrderByDescending(h => h.Date).ToList();
+
+ // return Json(new
+ // {
+ // aaData = history
+ // },
+ // JsonRequestBehavior.AllowGet);
+ //}
+
+ public ActionResult AjaxBinding(DataTablesPageRequest pageRequest)
{
- var history = _historyProvider.AllItemsWithRelationships().Select(h => new HistoryModel
+ var pageResult = _historyProvider.GetPagedItems(pageRequest);
+ var totalItems = _historyProvider.Count();
+
+ var items = pageResult.Items.Select(h => new HistoryModel
{
HistoryId = h.HistoryId,
SeriesId = h.SeriesId,
- EpisodeNumbering = string.Format("{0}x{1:00}", h.Episode.SeasonNumber, h.Episode.EpisodeNumber),
- EpisodeTitle = h.Episode.Title,
- EpisodeOverview = h.Episode.Overview,
+ EpisodeNumbering = string.Format("{0}x{1:00}", h.SeasonNumber, h.EpisodeNumber),
+ EpisodeTitle = h.EpisodeTitle,
+ EpisodeOverview = h.EpisodeOverview,
SeriesTitle = h.SeriesTitle,
SeriesTitleSorter = SortHelper.SkipArticles(h.SeriesTitle),
NzbTitle = h.NzbTitle,
@@ -43,11 +77,14 @@ namespace NzbDrone.Web.Controllers
Indexer = h.Indexer,
EpisodeId = h.EpisodeId,
NzbInfoUrl = h.NzbInfoUrl
- }).OrderByDescending(h => h.Date).ToList();
+ });
return Json(new
{
- aaData = history
+ sEcho = pageRequest.Echo,
+ iTotalRecords = totalItems,
+ iTotalDisplayRecords = pageResult.TotalItems,
+ aaData = items
},
JsonRequestBehavior.AllowGet);
}
diff --git a/NzbDrone.Web/Controllers/LogController.cs b/NzbDrone.Web/Controllers/LogController.cs
index 6df8bd2ad..bc31e062a 100644
--- a/NzbDrone.Web/Controllers/LogController.cs
+++ b/NzbDrone.Web/Controllers/LogController.cs
@@ -52,36 +52,36 @@ namespace NzbDrone.Web.Controllers
return JsonNotificationResult.Info("Logs Cleared");
}
- public ActionResult AjaxBinding(DataTablesParams dataTablesParams)
+ public ActionResult AjaxBinding(DataTablesPageRequest pageRequest)
{
var logs = _logProvider.GetAllLogs();
var totalCount = logs.Count();
IQueryable q = logs;
- if (!string.IsNullOrEmpty(dataTablesParams.sSearch))
+ if (!string.IsNullOrEmpty(pageRequest.Search))
{
- q = q.Where(b => b.Logger.Contains(dataTablesParams.sSearch)
- || b.Exception.Contains(dataTablesParams.sSearch)
- || b.Message.Contains(dataTablesParams.sSearch));
+ q = q.Where(b => b.Logger.Contains(pageRequest.Search)
+ || b.Exception.Contains(pageRequest.Search)
+ || b.Message.Contains(pageRequest.Search));
}
int filteredCount = q.Count();
IQueryable sorted = q;
- for (int i = 0; i < dataTablesParams.iSortingCols; i++)
+ for (int i = 0; i < pageRequest.SortingCols; i++)
{
- int sortCol = dataTablesParams.iSortCol[i];
+ int sortCol = pageRequest.SortCol[i];
var sortColName = sortCol == 0 ? "Time" : sortCol == 1 ? "Level" : "Logger";
- var sortExpression = String.Format("{0} {1}", sortColName, dataTablesParams.sSortDir[i]);
+ var sortExpression = String.Format("{0} {1}", sortColName, pageRequest.SortDir[i]);
sorted = sorted.OrderBy(sortExpression);
}
IQueryable filteredAndSorted = sorted;
- if (filteredCount > dataTablesParams.iDisplayLength)
+ if (filteredCount > pageRequest.DisplayLength)
{
- filteredAndSorted = sorted.Skip(dataTablesParams.iDisplayStart).Take(dataTablesParams.iDisplayLength);
+ filteredAndSorted = sorted.Skip(pageRequest.DisplayStart).Take(pageRequest.DisplayLength);
}
var logModels = filteredAndSorted.ToList().Select(s => new LogModel
@@ -97,7 +97,7 @@ namespace NzbDrone.Web.Controllers
return Json(new
{
- sEcho = dataTablesParams.sEcho,
+ sEcho = pageRequest.Echo,
iTotalRecords = totalCount,
iTotalDisplayRecords = filteredCount,
aaData = logModels
diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj
index 74005fcb6..060760cef 100644
--- a/NzbDrone.Web/NzbDrone.Web.csproj
+++ b/NzbDrone.Web/NzbDrone.Web.csproj
@@ -53,9 +53,9 @@
x86
-
- ..\packages\DataTables.Mvc.0.1.0.79\lib\DataTables.Mvc.Core.dll
- True
+
+ False
+ ..\packages\DataTables.Mvc.Core.0.1.0.85\lib\DataTables.Mvc.Core.dll
..\packages\DynamicQuery.1.0\lib\35\Dynamic.dll
@@ -142,9 +142,9 @@
False
..\Libraries\TvdbLib.dll
-
+
False
- ..\packages\WebActivator.1.5\lib\net40\WebActivator.dll
+ ..\packages\WebActivator.1.5.1\lib\net40\WebActivator.dll
@@ -363,6 +363,7 @@
+
diff --git a/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js b/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js
new file mode 100644
index 000000000..f020aca48
--- /dev/null
+++ b/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js
@@ -0,0 +1,33 @@
+$.fn.dataTableExt.oApi.fnSetFilteringDelay = function (oSettings, iDelay) {
+ /*
+ * Inputs: object:oSettings - dataTables settings object - automatically given
+ * integer:iDelay - delay in milliseconds
+ * Usage: $('#example').dataTable().fnSetFilteringDelay(250);
+ * Author: Zygimantas Berziunas (www.zygimantas.com) and Allan Jardine
+ * License: GPL v2 or BSD 3 point style
+ * Contact: zygimantas.berziunas /AT\ hotmail.com
+ */
+ var _that = this,
+ iDelay = (typeof iDelay == 'undefined') ? 250 : iDelay;
+
+ this.each(function (i) {
+ $.fn.dataTableExt.iApiIndex = i;
+ var oTimerId = null,
+ sPreviousSearch = null,
+ anControl = $('input', _that.fnSettings().aanFeatures.f);
+
+ anControl.unbind('keyup').bind('keyup', function () {
+ if (sPreviousSearch === null || sPreviousSearch != anControl.val()) {
+ window.clearTimeout(oTimerId);
+ sPreviousSearch = anControl.val();
+ oTimerId = window.setTimeout(function () {
+ $.fn.dataTableExt.iApiIndex = i;
+ _that.fnFilter(anControl.val());
+ }, iDelay);
+ }
+ });
+
+ return this;
+ });
+ return this;
+};
\ No newline at end of file
diff --git a/NzbDrone.Web/Views/History/Index.cshtml b/NzbDrone.Web/Views/History/Index.cshtml
index efbddff65..216969c13 100644
--- a/NzbDrone.Web/Views/History/Index.cshtml
+++ b/NzbDrone.Web/Views/History/Index.cshtml
@@ -46,7 +46,7 @@
oTable = $('#historyGrid').dataTable({
"sAjaxSource": "History/AjaxBinding",
- "bServerSide": false,
+ "bServerSide": true,
"bProcessing": true,
"bShowAll": false,
"bPaginate": true,
@@ -59,7 +59,7 @@
"sPaginationType": "four_button",
"aoColumns": [
{
- sWidth: '20px', "bSortable": false, "mDataProp": function (source, type, val) {
+ sName: 'Icon', sWidth: '20px', "bSortable": false, "bSearchable": false, "mDataProp": function (source, type, val) {
// 'display' and 'filter' use the image
if (type === 'display' || type === 'filter') {
if (source['Indexer'].indexOf("Newznab") === 0)
@@ -71,7 +71,8 @@
return source["Indexer"];
}
}, //Image
- { sWidth: 'auto', "mDataProp": function (source, type, val) {
+ {
+ sName: 'Series.Title', sWidth: 'auto', "mDataProp": function (source, type, val) {
// 'display' and 'filter' use our fancy naming
if (type === 'display' || type === 'filter') {
return "" + source["SeriesTitle"] + "";
@@ -80,10 +81,10 @@
return source["SeriesTitleSorter"];
}
}, //Series Title
- { sWidth: '80px', "mDataProp": "EpisodeNumbering", "bSortable": false }, //EpisodeNumbering
- { sWidth: 'auto', "mDataProp": "EpisodeTitle", "bSortable": false }, //Episode Title
- { sWidth: '70px', "mDataProp": "Quality", "bSortable": false }, //Quality
- { sWidth: '150px', "mDataProp": function (source, type, val) {
+ { sName: 'EpisodeNumbering', sWidth: '80px', "mDataProp": "EpisodeNumbering", "bSortable": false, "bSearchable": false }, //EpisodeNumbering
+ { sName: 'Episodes.Title', sWidth: 'auto', "mDataProp": "EpisodeTitle", "bSortable": false }, //Episode Title
+ { sName: 'Quality', sWidth: '70px', "mDataProp": "Quality", "bSortable": false, "bSearchable": false }, //Quality
+ { sName: 'Date', sWidth: '150px', "bSearchable": false, "mDataProp": function (source, type, val) {
// 'display' and 'filter' use our fancy naming
if (type === 'display' || type === 'filter') {
return source["Date"];
@@ -92,7 +93,7 @@
return source["DateSorter"];
}
}, //Date
- { sWidth: '40px', "mDataProp": "HistoryId", "bSortable": false, "fnRender": function (row) {
+ { sName: 'Actions', sWidth: '40px', "mDataProp": "HistoryId", "bSortable": false, "bSearchable": false, "fnRender": function (row) {
var deleteImage = "";
var redownloadImage = "";
@@ -100,9 +101,10 @@
}
}, //Actions
{
- sWidth: 'auto',
+ sName: 'Details', sWidth: 'auto',
"mDataProp": "Details",
"bSortable": false,
+ "bSearchable": false,
"bVisible": false,
"fnRender": function(row) {
var result = "Overview: " + row.aData["EpisodeOverview"] + "
" +
@@ -118,7 +120,7 @@
} //Details
],
"aaSorting": [[5, 'desc']]
- });
+ }).fnSetFilteringDelay(500);
});
function deleteHistory(row, historyId) {
diff --git a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml
index 598fdf8c7..e4207762c 100644
--- a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml
+++ b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml
@@ -44,7 +44,8 @@
@Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.min.js")
@Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.reloadAjax.js")
@Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.editable.js")
- @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.jeditable.js")
+ @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.jeditable.js")s
+ @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTablesFilteringDelay.js")
@Html.IncludeScript("jquery.dataTables.4button.pagination.js")
@RenderSection("Scripts", required: false)