From 6941888832a79bc1117cbe789346a965c6cb69a1 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Fri, 4 Jul 2014 22:07:03 +0200 Subject: [PATCH] Updated sorting architecture so the collections can specify the sort-oddities instead of in backgrid column definitions. --- src/NzbDrone.Api/Blacklist/BlacklistModule.cs | 6 --- src/NzbDrone.Api/History/HistoryModule.cs | 6 --- src/NzbDrone.Api/Wanted/CutoffModule.cs | 6 --- src/NzbDrone.Api/Wanted/MissingModule.cs | 6 --- .../History/Blacklist/BlacklistCollection.js | 12 +++-- src/UI/History/Blacklist/BlacklistLayout.js | 6 +-- src/UI/History/HistoryCollection.js | 14 +++-- src/UI/History/Table/HistoryTableLayout.js | 3 +- src/UI/Mixins/AsPersistedStateCollection.js | 27 ++++------ src/UI/Mixins/AsSortedCollection.js | 45 ++++++++++++++++ src/UI/Series/Editor/SeriesEditorLayout.js | 3 +- src/UI/Series/Index/SeriesIndexLayout.js | 8 ++- src/UI/Series/SeriesCollection.js | 44 ++++++++------- src/UI/Shared/Grid/HeaderCell.js | 53 +++++++++++-------- src/UI/Shared/Toolbar/ButtonModel.js | 14 ----- .../Sorting/SortingButtonCollectionView.js | 47 ++-------------- .../Toolbar/Sorting/SortingButtonView.js | 25 ++++----- src/UI/System/Logs/Files/LogFileLayout.js | 6 ++- src/UI/Wanted/Cutoff/CutoffUnmetCollection.js | 14 +++-- src/UI/Wanted/Missing/MissingCollection.js | 14 +++-- 20 files changed, 173 insertions(+), 186 deletions(-) create mode 100644 src/UI/Mixins/AsSortedCollection.js diff --git a/src/NzbDrone.Api/Blacklist/BlacklistModule.cs b/src/NzbDrone.Api/Blacklist/BlacklistModule.cs index bfbcbc2de..6fb9e73b8 100644 --- a/src/NzbDrone.Api/Blacklist/BlacklistModule.cs +++ b/src/NzbDrone.Api/Blacklist/BlacklistModule.cs @@ -25,12 +25,6 @@ namespace NzbDrone.Api.Blacklist SortDirection = pagingResource.SortDirection }; - //This is a hack to deal with backgrid setting the sortKey to the column name instead of sortValue - if (pagingSpec.SortKey.Equals("series", StringComparison.InvariantCultureIgnoreCase)) - { - pagingSpec.SortKey = "series.sortTitle"; - } - return ApplyToPage(_blacklistService.Paged, pagingSpec); } diff --git a/src/NzbDrone.Api/History/HistoryModule.cs b/src/NzbDrone.Api/History/HistoryModule.cs index ded75c54c..119ea1e68 100644 --- a/src/NzbDrone.Api/History/HistoryModule.cs +++ b/src/NzbDrone.Api/History/HistoryModule.cs @@ -33,12 +33,6 @@ namespace NzbDrone.Api.History SortDirection = pagingResource.SortDirection }; - //This is a hack to deal with backgrid setting the sortKey to the column name instead of sortValue - if (pagingSpec.SortKey.Equals("series", StringComparison.InvariantCultureIgnoreCase)) - { - pagingSpec.SortKey = "series.sortTitle"; - } - if (pagingResource.FilterKey == "eventType") { var filterValue = (HistoryEventType)Convert.ToInt32(pagingResource.FilterValue); diff --git a/src/NzbDrone.Api/Wanted/CutoffModule.cs b/src/NzbDrone.Api/Wanted/CutoffModule.cs index f4fd267ba..384ee43ac 100644 --- a/src/NzbDrone.Api/Wanted/CutoffModule.cs +++ b/src/NzbDrone.Api/Wanted/CutoffModule.cs @@ -31,12 +31,6 @@ namespace NzbDrone.Api.Wanted SortDirection = pagingResource.SortDirection }; - //This is a hack to deal with backgrid setting the sortKey to the column name instead of sortValue - if (pagingSpec.SortKey.Equals("series", StringComparison.InvariantCultureIgnoreCase)) - { - pagingSpec.SortKey = "series.sortTitle"; - } - if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false") { pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false; diff --git a/src/NzbDrone.Api/Wanted/MissingModule.cs b/src/NzbDrone.Api/Wanted/MissingModule.cs index 8852f0ae8..f551cdd67 100644 --- a/src/NzbDrone.Api/Wanted/MissingModule.cs +++ b/src/NzbDrone.Api/Wanted/MissingModule.cs @@ -31,12 +31,6 @@ namespace NzbDrone.Api.Wanted SortDirection = pagingResource.SortDirection }; - //This is a hack to deal with backgrid setting the sortKey to the column name instead of sortValue - if (pagingSpec.SortKey.Equals("series", StringComparison.InvariantCultureIgnoreCase)) - { - pagingSpec.SortKey = "series.sortTitle"; - } - if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false") { pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false; diff --git a/src/UI/History/Blacklist/BlacklistCollection.js b/src/UI/History/Blacklist/BlacklistCollection.js index 3dcdb7cab..49d49a700 100644 --- a/src/UI/History/Blacklist/BlacklistCollection.js +++ b/src/UI/History/Blacklist/BlacklistCollection.js @@ -3,9 +3,10 @@ define( [ 'History/Blacklist/BlacklistModel', 'backbone.pageable', + 'Mixins/AsSortedCollection', 'Mixins/AsPersistedStateCollection' - ], function (BlacklistModel, PageableCollection, AsPersistedStateCollection) { - var collection = PageableCollection.extend({ + ], function (BlacklistModel, PageableCollection, AsSortedCollection, AsPersistedStateCollection) { + var Collection = PageableCollection.extend({ url : window.NzbDrone.ApiRoot + '/blacklist', model: BlacklistModel, @@ -27,6 +28,10 @@ define( } }, + sortMappings: { + 'series' : { sortKey: 'series.sortTitle' } + }, + parseState: function (resp) { return { totalRecords: resp.totalRecords }; }, @@ -40,5 +45,6 @@ define( } }); - return AsPersistedStateCollection.apply(collection); + Collection = AsSortedCollection.call(Collection); + return AsPersistedStateCollection.call(Collection); }); diff --git a/src/UI/History/Blacklist/BlacklistLayout.js b/src/UI/History/Blacklist/BlacklistLayout.js index c1476f6f7..d91abe620 100644 --- a/src/UI/History/Blacklist/BlacklistLayout.js +++ b/src/UI/History/Blacklist/BlacklistLayout.js @@ -37,14 +37,12 @@ define( { name : 'series', label : 'Series', - cell : SeriesTitleCell, - sortValue : 'series.sortTitle' + cell : SeriesTitleCell }, { name : 'sourceTitle', label : 'Source Title', - cell : 'string', - sortValue : 'sourceTitle' + cell : 'string' }, { name : 'quality', diff --git a/src/UI/History/HistoryCollection.js b/src/UI/History/HistoryCollection.js index 623e38cee..82292715c 100644 --- a/src/UI/History/HistoryCollection.js +++ b/src/UI/History/HistoryCollection.js @@ -4,9 +4,10 @@ define( 'History/HistoryModel', 'backbone.pageable', 'Mixins/AsFilteredCollection', + 'Mixins/AsSortedCollection', 'Mixins/AsPersistedStateCollection' - ], function (HistoryModel, PageableCollection, AsFilteredCollection, AsPersistedStateCollection) { - var collection = PageableCollection.extend({ + ], function (HistoryModel, PageableCollection, AsFilteredCollection, AsSortedCollection, AsPersistedStateCollection) { + var Collection = PageableCollection.extend({ url : window.NzbDrone.ApiRoot + '/history', model: HistoryModel, @@ -35,6 +36,10 @@ define( 'failed' : ['eventType', '4'] }, + sortMappings: { + 'series' : { sortKey: 'series.sortTitle' } + }, + initialize: function (options) { delete this.queryParams.episodeId; @@ -58,6 +63,7 @@ define( } }); - collection = AsFilteredCollection.call(collection); - return AsPersistedStateCollection.call(collection); + Collection = AsFilteredCollection.call(Collection); + Collection = AsSortedCollection.call(Collection); + return AsPersistedStateCollection.call(Collection); }); diff --git a/src/UI/History/Table/HistoryTableLayout.js b/src/UI/History/Table/HistoryTableLayout.js index baab97395..d4df0fc71 100644 --- a/src/UI/History/Table/HistoryTableLayout.js +++ b/src/UI/History/Table/HistoryTableLayout.js @@ -47,8 +47,7 @@ define( { name : 'series', label : 'Series', - cell : SeriesTitleCell, - sortValue : 'series.sortTitle' + cell : SeriesTitleCell }, { name : 'episode', diff --git a/src/UI/Mixins/AsPersistedStateCollection.js b/src/UI/Mixins/AsPersistedStateCollection.js index d4177f1a4..e07c2b0d8 100644 --- a/src/UI/Mixins/AsPersistedStateCollection.js +++ b/src/UI/Mixins/AsPersistedStateCollection.js @@ -7,7 +7,6 @@ define( return function () { var originalInit = this.prototype.initialize; - this.prototype.initialize = function (options) { options = options || {}; @@ -30,18 +29,24 @@ define( } }; + if (!this.prototype._getSortMapping) { + this.prototype._getSortMapping = function(key) { + return { name: key, sortKey: key }; + }; + } + var _setInitialState = function () { var key = Config.getValue('{0}.sortKey'.format(this.tableName), this.state.sortKey); var direction = Config.getValue('{0}.sortDirection'.format(this.tableName), this.state.order); var order = parseInt(direction, 10); - this.state.sortKey = key; + this.state.sortKey = this._getSortMapping(key).sortKey; this.state.order = order; }; var _storeStateFromBackgrid = function (column, sortDirection) { var order = _convertDirectionToInt(sortDirection); - var sortKey = column.has('sortValue') && _.isString(column.get('sortValue')) ? column.get('sortValue') : column.get('name'); + var sortKey = this._getSortMapping(column.get('name')).sortKey; Config.setValue('{0}.sortKey'.format(this.tableName), sortKey); Config.setValue('{0}.sortDirection'.format(this.tableName), order); @@ -49,7 +54,7 @@ define( var _storeState = function (sortModel, sortDirection) { var order = _convertDirectionToInt(sortDirection); - var sortKey = sortModel.get('name'); + var sortKey = this._getSortMapping(sortModel.get('name')).sortKey; Config.setValue('{0}.sortKey'.format(this.tableName), sortKey); Config.setValue('{0}.sortDirection'.format(this.tableName), order); @@ -62,20 +67,6 @@ define( return '1'; }; - - var originalMakeComparator = this.prototype._makeComparator; - this.prototype._makeComparator = function (sortKey, order, sortValue) { - var state = this.state; - - sortKey = sortKey || state.sortKey; - order = order || state.order; - - if (!sortKey || !order) return; - - if (!sortValue && this[sortKey]) sortValue = this[sortKey]; - - return originalMakeComparator.call(this, sortKey, order, sortValue); - }; return this; }; diff --git a/src/UI/Mixins/AsSortedCollection.js b/src/UI/Mixins/AsSortedCollection.js new file mode 100644 index 000000000..d49aa216f --- /dev/null +++ b/src/UI/Mixins/AsSortedCollection.js @@ -0,0 +1,45 @@ +'use strict'; + +define( + ['underscore', 'Config'], + function (_, Config) { + + return function () { + + this.prototype._getSortMappings = function () { + var result = {}; + + if (this.sortMappings) { + _.each(this.sortMappings, function (values, key) { + var item = { + name: key, + sortKey: values.sortKey || key, + sortValue: values.sortValue + }; + result[key] = item; + result[item.sortKey] = item; + }); + } + + return result; + }; + + this.prototype._getSortMapping = function (key) { + var sortMappings = this._getSortMappings(); + + return sortMappings[key] || { name: key, sortKey: key }; + }; + + var originalSetSorting = this.prototype.setSorting; + this.prototype.setSorting = function (sortKey, order, options) { + var sortMapping = this._getSortMapping(sortKey); + + options = _.defaults({ sortValue: sortMapping.sortValue }, options || {}); + + return originalSetSorting.call(this, sortMapping.sortKey, order, options); + }; + + return this; + }; + } +); diff --git a/src/UI/Series/Editor/SeriesEditorLayout.js b/src/UI/Series/Editor/SeriesEditorLayout.js index dc0b7f972..b296539d7 100644 --- a/src/UI/Series/Editor/SeriesEditorLayout.js +++ b/src/UI/Series/Editor/SeriesEditorLayout.js @@ -60,8 +60,7 @@ define( name : 'title', label : 'Title', cell : SeriesTitleCell, - cellValue : 'this', - sortValue : 'sortTitle' + cellValue : 'this' }, { name : 'qualityProfileId', diff --git a/src/UI/Series/Index/SeriesIndexLayout.js b/src/UI/Series/Index/SeriesIndexLayout.js index fb9782817..f0f773d58 100644 --- a/src/UI/Series/Index/SeriesIndexLayout.js +++ b/src/UI/Series/Index/SeriesIndexLayout.js @@ -77,8 +77,7 @@ define( { name : 'nextAiring', label : 'Next Airing', - cell : RelativeDateCell, - sortValue : SeriesCollection.nextAiring + cell : RelativeDateCell }, { name : 'percentOfEpisodes', @@ -173,9 +172,8 @@ define( name : 'network' }, { - title : 'Next Airing', - name : 'nextAiring', - sortValue : SeriesCollection.nextAiring + title: 'Next Airing', + name : 'nextAiring' }, { title: 'Episodes', diff --git a/src/UI/Series/SeriesCollection.js b/src/UI/Series/SeriesCollection.js index 45fb8dc2b..bc4183eb7 100644 --- a/src/UI/Series/SeriesCollection.js +++ b/src/UI/Series/SeriesCollection.js @@ -7,16 +7,17 @@ define( 'Series/SeriesModel', 'api!series', 'Mixins/AsFilteredCollection', + 'Mixins/AsSortedCollection', 'Mixins/AsPersistedStateCollection', 'moment' - ], function (_, Backbone, PageableCollection, SeriesModel, SeriesData, AsFilteredCollection, AsPersistedStateCollection, Moment) { + ], function (_, Backbone, PageableCollection, SeriesModel, SeriesData, AsFilteredCollection, AsSortedCollection, AsPersistedStateCollection, Moment) { var Collection = PageableCollection.extend({ url : window.NzbDrone.ApiRoot + '/series', model: SeriesModel, tableName: 'series', state: { - sortKey: 'title', + sortKey: 'sortTitle', order : -1, pageSize: 100000 }, @@ -56,27 +57,30 @@ define( 'monitored' : ['monitored', true] }, - //Sorters - nextAiring: function (model, attr) { - var nextAiring = model.get(attr); - - if (nextAiring) { - return Moment(nextAiring).unix(); - } - - var previousAiring = model.get(attr.replace('nextAiring', 'previousAiring')); - - if (previousAiring) { - return 10000000000 - Moment(previousAiring).unix(); - } + sortMappings: { + 'title' : { sortKey: 'sortTitle' }, + 'nextAiring' : { sortValue: function (model, attr) { + var nextAiring = model.get(attr); + + if (nextAiring) { + return Moment(nextAiring).unix(); + } + + var previousAiring = model.get(attr.replace('nextAiring', 'previousAiring')); + + if (previousAiring) { + return 10000000000 - Moment(previousAiring).unix(); + } - return Number.MAX_VALUE; + return Number.MAX_VALUE; + } + } } }); - var FilteredCollection = AsFilteredCollection.call(Collection); - var MixedIn = AsPersistedStateCollection.call(FilteredCollection); - var collection = new MixedIn(SeriesData, { full: true }); + Collection = AsFilteredCollection.call(Collection); + Collection = AsSortedCollection.call(Collection); + Collection = AsPersistedStateCollection.call(Collection); - return collection; + return new Collection(SeriesData, { full: true }); }); diff --git a/src/UI/Shared/Grid/HeaderCell.js b/src/UI/Shared/Grid/HeaderCell.js index 45b402589..7f0b71cde 100644 --- a/src/UI/Shared/Grid/HeaderCell.js +++ b/src/UI/Shared/Grid/HeaderCell.js @@ -39,13 +39,12 @@ define( this.direction(column.get('direction')); if (this.collection.state) { - var key = this.collection.state.sortKey; + var name = this._getSortMapping().name; var order = this.collection.state.order; - if (key === this.column.get('name')) { + if (name === column.get('name')) { this._setSortIcon(order); } - else { this._removeSortIcon(); } @@ -69,10 +68,10 @@ define( var columnDirection = this.column.get('direction'); if (!columnDirection && this.collection.state) { - var key = this.collection.state.sortKey; + var name = this._getSortMapping().name; var order = this.collection.state.order; - if (key === this.column.get('name')) { + if (name === this.column.get('name')) { columnDirection = order; } } @@ -80,31 +79,41 @@ define( return columnDirection; }, + _getSortMapping: function() { + var sortKey = this.collection.state.sortKey; + + if (this.collection._getSortMapping) { + return this.collection._getSortMapping(sortKey); + } + + return { name: sortKey, sortKey: sortKey }; + }, + onClick: function (e) { e.preventDefault(); var collection = this.collection; var event = 'backgrid:sort'; - function toggleSort(header, col) { - collection.state.sortKey = col.get('name'); - var direction = header.direction(); - if (direction === 'ascending' || direction === -1) - { - collection.state.order = 'descending'; - collection.trigger(event, col, 'descending'); - } - else - { - collection.state.order = 'ascending'; - collection.trigger(event, col, 'ascending'); - } - } - var column = this.column; - var sortable = Backgrid.callByNeed(column.sortable(), column, this.collection); + var sortable = Backgrid.callByNeed(column.sortable(), column, collection); if (sortable) { - toggleSort(this, column); + var direction = collection.state.order; + if (direction === 'ascending' || direction === -1) { + direction = 'descending'; + } + else { + direction = 'ascending'; + } + + if (collection.setSorting) { + collection.setSorting(column.get('name'), direction); + } + else { + collection.state.sortKey = column.get('name'); + collection.state.order = direction; + } + collection.trigger(event, column, direction); } }, diff --git a/src/UI/Shared/Toolbar/ButtonModel.js b/src/UI/Shared/Toolbar/ButtonModel.js index b7bd6d4dc..9ea428ed7 100644 --- a/src/UI/Shared/Toolbar/ButtonModel.js +++ b/src/UI/Shared/Toolbar/ButtonModel.js @@ -10,20 +10,6 @@ define( 'title' : '', 'active' : false, 'tooltip': undefined - }, - - sortValue: function () { - var sortValue = this.get('sortValue'); - if (_.isString(sortValue)) { - return this[sortValue]; - } - else if (_.isFunction(sortValue)) { - return sortValue; - } - - return function (model, colName) { - return model.get(colName); - }; } }); }); diff --git a/src/UI/Shared/Toolbar/Sorting/SortingButtonCollectionView.js b/src/UI/Shared/Toolbar/Sorting/SortingButtonCollectionView.js index a79abc2f0..f5e386db2 100644 --- a/src/UI/Shared/Toolbar/Sorting/SortingButtonCollectionView.js +++ b/src/UI/Shared/Toolbar/Sorting/SortingButtonCollectionView.js @@ -34,52 +34,11 @@ define( else { order = null; } - - var comparator = this.makeComparator(sortModel.get('name'), order, - order ? - sortModel.sortValue() : - function (model) { - return model.cid; - }); - - if (PageableCollection && - collection instanceof PageableCollection) { - - collection.setSorting(order && sortModel.get('name'), order, - {sortValue: sortModel.sortValue()}); - - if (collection.mode === 'client') { - if (collection.fullCollection.comparator === null) { - collection.fullCollection.comparator = comparator; - } - collection.fullCollection.sort(); - } - else { - collection.fetch({reset: true}); - } - } - else { - collection.comparator = comparator; - collection.sort(); - } + + collection.setSorting(sortModel.get('name'), order); + collection.fullCollection.sort(); return this; - }, - - makeComparator: function (attr, order, func) { - - return function (left, right) { - // extract the values from the models - var l = func(left, attr), r = func(right, attr), t; - - // if descending order, swap left and right - if (order === 1) t = l, l = r, r = t; - - // compare as usual - if (l === r) return 0; - else if (l < r) return -1; - return 1; - }; } }); }); diff --git a/src/UI/Shared/Toolbar/Sorting/SortingButtonView.js b/src/UI/Shared/Toolbar/Sorting/SortingButtonView.js index 7421e628f..2ecb00182 100644 --- a/src/UI/Shared/Toolbar/Sorting/SortingButtonView.js +++ b/src/UI/Shared/Toolbar/Sorting/SortingButtonView.js @@ -26,13 +26,13 @@ define( onRender: function () { if (this.viewCollection.state) { - var key = this.viewCollection.state.sortKey; + var sortKey = this.viewCollection.state.sortKey; + var name = this.viewCollection._getSortMapping(sortKey).name; var order = this.viewCollection.state.order; - if (key === this.model.get('name')) { + if (name === this.model.get('name')) { this._setSortIcon(order); } - else { this._removeSortIcon(); } @@ -45,19 +45,16 @@ define( var collection = this.viewCollection; var event = 'drone:sort'; - collection.state.sortKey = this.model.get('name'); var direction = collection.state.order; + if (direction === 'ascending' || direction === -1) { + direction = 'descending'; + } + else { + direction = 'ascending'; + } - if (direction === 'ascending' || direction === -1) - { - collection.state.order = 'descending'; - collection.trigger(event, this.model, 'descending'); - } - else - { - collection.state.order = 'ascending'; - collection.trigger(event, this.model, 'ascending'); - } + collection.setSorting(this.model.get('name'), direction); + collection.trigger(event, this.model, direction); }, _convertDirectionToIcon: function (dir) { diff --git a/src/UI/System/Logs/Files/LogFileLayout.js b/src/UI/System/Logs/Files/LogFileLayout.js index 75280515a..d6ce0cf7a 100644 --- a/src/UI/System/Logs/Files/LogFileLayout.js +++ b/src/UI/System/Logs/Files/LogFileLayout.js @@ -38,12 +38,14 @@ define( { name : 'filename', label: 'Filename', - cell : FilenameCell + cell : FilenameCell, + sortable: false }, { name : 'lastWriteTime', label: 'Last Write Time', - cell : RelativeDateCell + cell : RelativeDateCell, + sortable: false }, { name : 'downloadUrl', diff --git a/src/UI/Wanted/Cutoff/CutoffUnmetCollection.js b/src/UI/Wanted/Cutoff/CutoffUnmetCollection.js index a42c12dba..ad2e40ac9 100644 --- a/src/UI/Wanted/Cutoff/CutoffUnmetCollection.js +++ b/src/UI/Wanted/Cutoff/CutoffUnmetCollection.js @@ -5,9 +5,10 @@ define( 'Series/EpisodeModel', 'backbone.pageable', 'Mixins/AsFilteredCollection', + 'Mixins/AsSortedCollection', 'Mixins/AsPersistedStateCollection' - ], function (_, EpisodeModel, PagableCollection, AsFilteredCollection, AsPersistedStateCollection) { - var collection = PagableCollection.extend({ + ], function (_, EpisodeModel, PagableCollection, AsFilteredCollection, AsSortedCollection, AsPersistedStateCollection) { + var Collection = PagableCollection.extend({ url : window.NzbDrone.ApiRoot + '/wanted/cutoff', model: EpisodeModel, tableName: 'wanted.cutoff', @@ -36,6 +37,10 @@ define( 'unmonitored' : ['monitored', 'false'], }, + sortMappings: { + 'series' : { sortKey: 'series.sortTitle' } + }, + parseState: function (resp) { return {totalRecords: resp.totalRecords}; }, @@ -49,6 +54,7 @@ define( } }); - collection = AsFilteredCollection.call(collection); - return AsPersistedStateCollection.call(collection); + Collection = AsFilteredCollection.call(Collection); + Collection = AsSortedCollection.call(Collection); + return AsPersistedStateCollection.call(Collection); }); diff --git a/src/UI/Wanted/Missing/MissingCollection.js b/src/UI/Wanted/Missing/MissingCollection.js index 17a79995f..7f589e957 100644 --- a/src/UI/Wanted/Missing/MissingCollection.js +++ b/src/UI/Wanted/Missing/MissingCollection.js @@ -5,9 +5,10 @@ define( 'Series/EpisodeModel', 'backbone.pageable', 'Mixins/AsFilteredCollection', + 'Mixins/AsSortedCollection', 'Mixins/AsPersistedStateCollection' - ], function (_, EpisodeModel, PagableCollection, AsFilteredCollection, AsPersistedStateCollection) { - var collection = PagableCollection.extend({ + ], function (_, EpisodeModel, PagableCollection, AsFilteredCollection, AsSortedCollection, AsPersistedStateCollection) { + var Collection = PagableCollection.extend({ url : window.NzbDrone.ApiRoot + '/wanted/missing', model: EpisodeModel, tableName: 'wanted.missing', @@ -35,6 +36,10 @@ define( 'unmonitored' : ['monitored', 'false'] }, + sortMappings: { + 'series' : { sortKey: 'series.sortTitle' } + }, + parseState: function (resp) { return {totalRecords: resp.totalRecords}; }, @@ -48,6 +53,7 @@ define( } }); - collection = AsFilteredCollection.call(collection); - return AsPersistedStateCollection.call(collection); + Collection = AsFilteredCollection.call(Collection); + Collection = AsSortedCollection.call(Collection); + return AsPersistedStateCollection.call(Collection); });