diff --git a/NzbDrone.Api/Missing/MissingModule.cs b/NzbDrone.Api/Missing/MissingModule.cs index c0e81f05a..2acc848ac 100644 --- a/NzbDrone.Api/Missing/MissingModule.cs +++ b/NzbDrone.Api/Missing/MissingModule.cs @@ -28,7 +28,8 @@ namespace NzbDrone.Api.Missing var episodes = _episodeService.EpisodesWithoutFiles(includeSpecials); //TODO: Include the Series Title - return Mapper.Map, List>(episodes).AsResponse(); + //TODO: Remove Take(20) + return Mapper.Map, List>(episodes).Take(20).AsResponse(); } } } \ No newline at end of file diff --git a/NzbDrone.Core/Tv/EpisodeService.cs b/NzbDrone.Core/Tv/EpisodeService.cs index 937eda0ef..b891e5d28 100644 --- a/NzbDrone.Core/Tv/EpisodeService.cs +++ b/NzbDrone.Core/Tv/EpisodeService.cs @@ -95,7 +95,9 @@ namespace NzbDrone.Core.Tv public List EpisodesWithoutFiles(bool includeSpecials) { - return _episodeRepository.EpisodesWithoutFiles(includeSpecials); + var episodes = _episodeRepository.EpisodesWithoutFiles(includeSpecials); + + return LinkSeriesToEpisodes(episodes); } public List GetEpisodesByFileId(int episodeFileId) @@ -288,14 +290,8 @@ namespace NzbDrone.Core.Tv public List EpisodesBetweenDates(DateTime start, DateTime end) { var episodes = _episodeRepository.EpisodesBetweenDates(start.ToUniversalTime(), end.ToUniversalTime()); - var series = _seriesService.GetSeriesInList(episodes.Select(e => e.SeriesId).Distinct()); - - episodes.ForEach(e => - { - e.Series = series.SingleOrDefault(s => s.Id == e.SeriesId); - }); - return episodes; + return LinkSeriesToEpisodes(episodes); } public void Handle(EpisodeGrabbedEvent message) @@ -354,5 +350,17 @@ namespace NzbDrone.Core.Tv logger.Trace("Deleted episodes that no longer exist in TVDB for {0}", series.Id); } + + private List LinkSeriesToEpisodes(List episodes) + { + var series = _seriesService.GetSeriesInList(episodes.Select(e => e.SeriesId).Distinct()); + + episodes.ForEach(e => + { + e.Series = series.SingleOrDefault(s => s.Id == e.SeriesId); + }); + + return episodes; + } } } \ No newline at end of file diff --git a/UI/Controller.js b/UI/Controller.js index 24003eb1f..155326f51 100644 --- a/UI/Controller.js +++ b/UI/Controller.js @@ -4,7 +4,7 @@ define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Calendar/CalendarCollectionView', 'Shared/NotificationView', 'Shared/NotFoundView', 'MainMenuView', 'Series/Details/SeriesDetailsView', 'Series/EpisodeCollection', - 'Settings/SettingsLayout', 'Missing/MissingCollectionView'], + 'Settings/SettingsLayout', 'Missing/MissingLayout'], function (app, modalRegion) { var controller = Backbone.Marionette.Controller.extend({ @@ -58,12 +58,7 @@ define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', missing: function () { this._setTitle('Missing'); - var missingCollection = new NzbDrone.Missing.MissingCollection(); - missingCollection.fetch({ - success: function () { - NzbDrone.mainRegion.show(new NzbDrone.Missing.MissingCollectionView({collection: missingCollection})); - } - }); + NzbDrone.mainRegion.show(new NzbDrone.Missing.MissingLayout()); }, notFound: function () { diff --git a/UI/Missing/MissingCollection.js b/UI/Missing/Collection.js similarity index 64% rename from UI/Missing/MissingCollection.js rename to UI/Missing/Collection.js index d8db13da4..26d6b3e5f 100644 --- a/UI/Missing/MissingCollection.js +++ b/UI/Missing/Collection.js @@ -1,6 +1,6 @@ "use strict"; -define(['app', 'Series/EpisodeModel'], function () { - NzbDrone.Missing.MissingCollection = Backbone.Collection.extend({ +define(['app'], function () { + NzbDrone.Missing.Collection = Backbone.PageableCollection.extend({ url : NzbDrone.Constants.ApiRoot + '/missing', model : NzbDrone.Series.EpisodeModel, comparator: function (model) { diff --git a/UI/Missing/ControlsColumnTemplate.html b/UI/Missing/ControlsColumnTemplate.html new file mode 100644 index 000000000..2783a2600 --- /dev/null +++ b/UI/Missing/ControlsColumnTemplate.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/UI/Missing/EpisodeColumnTemplate.html b/UI/Missing/EpisodeColumnTemplate.html new file mode 100644 index 000000000..30ab0a188 --- /dev/null +++ b/UI/Missing/EpisodeColumnTemplate.html @@ -0,0 +1,2 @@ + +{{seasonNumber}}x{{paddedEpisodeNumber}} \ No newline at end of file diff --git a/UI/Missing/MissingCollectionTemplate.html b/UI/Missing/MissingCollectionTemplate.html deleted file mode 100644 index a84b6a613..000000000 --- a/UI/Missing/MissingCollectionTemplate.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - -
Series TitleEpisodeEpisode TitleAir Date
-
-
- -
- -
-
-
\ No newline at end of file diff --git a/UI/Missing/MissingCollectionView.js b/UI/Missing/MissingCollectionView.js deleted file mode 100644 index e8d93ef0a..000000000 --- a/UI/Missing/MissingCollectionView.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict'; -define(['app', 'Missing/MissingItemView'], function () { - NzbDrone.Missing.MissingCollectionView = Backbone.Marionette.CompositeView.extend({ - itemView : NzbDrone.Missing.MissingItemView, - itemViewContainer: 'tbody', - template : 'Missing/MissingCollectionTemplate', - - ui: { - table: '.x-missing-table', - pager: '.x-missing-table-pager' - }, - - onCompositeCollectionRendered: function () { - this.ui.table.trigger('update'); - - if (!this.tableSorter && this.collection.length > 0) { - this.tableSorter = this.ui.table.tablesorter({ - textExtraction: function (node) { - return node.innerHTML; - }, - sortList : [ - [3, 1] - ], - headers : { - 0: { - sorter: 'innerHtml' - }, - 1: { - sorter: false - }, - 2: { - sorter: false - }, - 3: { - sorter: 'date' - }, - 4: { - sorter: false - } - } - }); - - this.ui.table.bind('pagerComplete pagerInitialized', function (event, c) { - c.container.find('.page-number').text(c.page + 1); - }); - - this.ui.table.tablesorterPager({ - container: this.ui.pager, - output : 'Displaying {startRow} to {endRow} of {totalRows} episodes' - }); - - this.applySortIcons(); - - this.ui.table.bind("sortEnd", function () { - this.applySortIcons(); - }); - } - else { - this.ui.table.trigger('update'); - } - }, - - //Todo: Remove this from each view that requires it - applySortIcons : function () { - $(this.ui.table).find('th.tablesorter-header .tablesorter-header-inner i').each(function () { - $(this).remove(); - }); - - $(this.ui.table).find('th.tablesorter-header').each(function () { - if ($(this).hasClass('tablesorter-headerDesc')) { - $(this).children('.tablesorter-header-inner').append(''); - } - - else if ($(this).hasClass('tablesorter-headerAsc')) { - $(this).children('.tablesorter-header-inner').append(''); - } - - else if (!$(this).hasClass('sorter-false')) { - $(this).children('.tablesorter-header-inner').append(''); - } - }); - }, - updatePageNumber : function (event, stuff) { - - } - }); -}); \ No newline at end of file diff --git a/UI/Missing/MissingItemTemplate.html b/UI/Missing/MissingItemTemplate.html deleted file mode 100644 index 4ef1004b9..000000000 --- a/UI/Missing/MissingItemTemplate.html +++ /dev/null @@ -1,5 +0,0 @@ -{{seriesTitle}} -{{seasonNumber}}x{{paddedEpisodeNumber}} - -{{bestDateString}} - \ No newline at end of file diff --git a/UI/Missing/MissingItemView.js b/UI/Missing/MissingItemView.js deleted file mode 100644 index 8b7c3e45f..000000000 --- a/UI/Missing/MissingItemView.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -define([ - 'app', - 'Missing/MissingCollection' - -], function () { - NzbDrone.Missing.MissingItemView = Backbone.Marionette.ItemView.extend({ - template: 'Missing/MissingItemTemplate', - tagName : 'tr', - }); -}); \ No newline at end of file diff --git a/UI/Missing/MissingLayout.js b/UI/Missing/MissingLayout.js new file mode 100644 index 000000000..b52ff7f8b --- /dev/null +++ b/UI/Missing/MissingLayout.js @@ -0,0 +1,84 @@ +"use strict"; +define([ + 'app', + 'Missing/Collection', + 'Series/Index/Table/AirDateCell', + 'Series/Index/Table/SeriesStatusCell', + 'Shared/Toolbar/ToolbarView', + 'Shared/Toolbar/ToolbarLayout' +], + function () { + NzbDrone.Missing.MissingLayout = Backbone.Marionette.Layout.extend({ + template: 'Missing/MissingLayoutTemplate', + + regions: { + missing: '#x-missing', + toolbar: '#x-toolbar' + }, + + showTable: function () { + + var columns = [ + { + name : 'seriesTitle', + label : 'Series Title', + editable : false, + cell : Backgrid.TemplateBackedCell.extend({ template: 'Missing/SeriesTitleTemplate' }), + headerCell: 'nzbDrone' + }, + { + name : 'episode', + label : 'Episode', + editable : false, + sortable : false, + cell : Backgrid.TemplateBackedCell.extend({ template: 'Missing/EpisodeColumnTemplate' }), + headerCell: 'nzbDrone' + }, + { + name : 'title', + label : 'Episode Title', + editable : false, + sortable : false, + cell : 'string', + headerCell: 'nzbDrone' + }, + { + name : 'airDate', + label : 'Air Date', + editable : false, + cell : 'airDate', + headerCell: 'nzbDrone' + }, + { + name : 'edit', + label : '', + editable : false, + sortable : false, + cell : Backgrid.TemplateBackedCell.extend({ template: 'Missing/ControlsColumnTemplate' }), + headerCell: 'nzbDrone' + } + ]; + + this.missing.show(new Backgrid.Grid( + { + row : NzbDrone.Missing.Row, + columns : columns, + collection: this.missingCollection, + className : 'table table-hover' + })); + }, + + initialize: function () { + this.missingCollection = new NzbDrone.Missing.Collection(); + this.missingCollection.fetch(); + }, + + onShow: function () { + this.showTable(); + //this.toolbar.show(new NzbDrone.Shared.Toolbar.ToolbarLayout({right: [ viewButtons], context: this})); + } + + }) + ; + }) +; diff --git a/UI/Missing/MissingLayoutTemplate.html b/UI/Missing/MissingLayoutTemplate.html new file mode 100644 index 000000000..a5013b74e --- /dev/null +++ b/UI/Missing/MissingLayoutTemplate.html @@ -0,0 +1,6 @@ +
+
+
+
+
+
diff --git a/UI/Missing/Row.js b/UI/Missing/Row.js new file mode 100644 index 000000000..76003b0f2 --- /dev/null +++ b/UI/Missing/Row.js @@ -0,0 +1,9 @@ +NzbDrone.Missing.Row = Backgrid.Row.extend({ + events: { + 'click .x-search' : 'search' + }, + + search: function () { + window.alert('Episode Search'); + } +}); \ No newline at end of file diff --git a/UI/Missing/SeriesTitleTemplate.html b/UI/Missing/SeriesTitleTemplate.html new file mode 100644 index 000000000..0a8c3ae09 --- /dev/null +++ b/UI/Missing/SeriesTitleTemplate.html @@ -0,0 +1 @@ +{{series.title}} \ No newline at end of file diff --git a/UI/Mixins/backbone.Backgrid.mixin.js b/UI/Mixins/backbone.Backgrid.mixin.js index 03c7fe93a..aaa69bc67 100644 --- a/UI/Mixins/backbone.Backgrid.mixin.js +++ b/UI/Mixins/backbone.Backgrid.mixin.js @@ -14,28 +14,6 @@ Backgrid.TemplateBackedCell = Backgrid.Cell.extend({ } }); -Backgrid.SeriesIndexTableRow = Backgrid.Row.extend({ - events: { - 'click .x-edit' : 'editSeries', - 'click .x-remove': 'removeSeries' - }, - - editSeries: function () { - var view = new NzbDrone.Series.Edit.EditSeriesView({ model: this.model}); - - NzbDrone.vent.trigger(NzbDrone.Events.OpenModalDialog, { - view: view - }); - }, - - removeSeries: function () { - var view = new NzbDrone.Series.Delete.DeleteSeriesView({ model: this.model }); - NzbDrone.vent.trigger(NzbDrone.Events.OpenModalDialog, { - view: view - }); - } -}); - Backgrid.NzbDroneHeaderCell = Backgrid.HeaderCell.extend({ events: { 'click': 'onClick' @@ -43,7 +21,6 @@ Backgrid.NzbDroneHeaderCell = Backgrid.HeaderCell.extend({ render: function () { this.$el.empty(); - var test = this.column.get('label'); this.$el.append(this.column.get("label")); if (this.column.get('sortable')) { diff --git a/UI/Series/Index/SeriesIndexLayout.js b/UI/Series/Index/SeriesIndexLayout.js index 8c96937ca..b5ad452bd 100644 --- a/UI/Series/Index/SeriesIndexLayout.js +++ b/UI/Series/Index/SeriesIndexLayout.js @@ -84,7 +84,7 @@ define([ this.series.show(new Backgrid.Grid( { - row : Backgrid.SeriesIndexTableRow, + row : NzbDrone.Series.Index.Table.Row, columns : columns, collection: this.seriesCollection, className : 'table table-hover' diff --git a/UI/Series/Index/SeriesIndexLayoutTemplate.html b/UI/Series/Index/SeriesIndexLayoutTemplate.html index 1911ff456..14a498c46 100644 --- a/UI/Series/Index/SeriesIndexLayoutTemplate.html +++ b/UI/Series/Index/SeriesIndexLayoutTemplate.html @@ -1,24 +1,4 @@ - -
+
diff --git a/UI/Series/Index/Table/Row.js b/UI/Series/Index/Table/Row.js new file mode 100644 index 000000000..ca7c0d901 --- /dev/null +++ b/UI/Series/Index/Table/Row.js @@ -0,0 +1,21 @@ +NzbDrone.Series.Index.Table.Row = Backgrid.Row.extend({ + events: { + 'click .x-edit' : 'editSeries', + 'click .x-remove': 'removeSeries' + }, + + editSeries: function () { + var view = new NzbDrone.Series.Edit.EditSeriesView({ model: this.model}); + + NzbDrone.vent.trigger(NzbDrone.Events.OpenModalDialog, { + view: view + }); + }, + + removeSeries: function () { + var view = new NzbDrone.Series.Delete.DeleteSeriesView({ model: this.model }); + NzbDrone.vent.trigger(NzbDrone.Events.OpenModalDialog, { + view: view + }); + } +}); \ No newline at end of file