mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-21 14:03:29 -07:00
removed backbone from VS solution,
renamed NzbDrone.Backbone to UI
This commit is contained in:
parent
c7776f74e1
commit
663160c06a
230 changed files with 57 additions and 386 deletions
17
UI/Series/Delete/DeleteSeriesTemplate.html
Normal file
17
UI/Series/Delete/DeleteSeriesTemplate.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Delete: {{title}}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Are you sure you want to delete '{{title}}'?</p>
|
||||
<div class="series-delete-files">
|
||||
<label class="checkbox">
|
||||
<input class="x-delete-files" type="checkbox" value="true">
|
||||
Delete all files from disk?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">cancel</button>
|
||||
<button class="btn btn-danger x-confirm-delete">delete</button>
|
||||
</div>
|
37
UI/Series/Delete/DeleteSeriesView.js
Normal file
37
UI/Series/Delete/DeleteSeriesView.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
define(['app', 'Series/SeriesModel'], function () {
|
||||
|
||||
NzbDrone.Series.Delete.DeleteSeriesView = Backbone.Marionette.ItemView.extend({
|
||||
template:'Series/Delete/DeleteSeriesTemplate',
|
||||
tagName:'div',
|
||||
className:"modal",
|
||||
|
||||
events:{
|
||||
'click .x-confirm-delete':'removeSeries'
|
||||
},
|
||||
|
||||
ui:{
|
||||
deleteFiles:'.x-delete-files'
|
||||
},
|
||||
|
||||
onRender:function () {
|
||||
NzbDrone.ModelBinder.bind(this.model, this.el);
|
||||
},
|
||||
|
||||
removeSeries:function () {
|
||||
|
||||
var deleteFiles = this.ui.deleteFiles.prop('checked');
|
||||
|
||||
this.model.destroy({
|
||||
data:{ 'deleteFiles':deleteFiles },
|
||||
success:function (model) {
|
||||
model.collection.remove(model);
|
||||
}
|
||||
});
|
||||
|
||||
NzbDrone.modalRegion.close();
|
||||
|
||||
}
|
||||
});
|
||||
});
|
1
UI/Series/Details/EpisodeItemTemplate.html
Normal file
1
UI/Series/Details/EpisodeItemTemplate.html
Normal file
|
@ -0,0 +1 @@
|
|||
{{title}}
|
19
UI/Series/Details/EpisodeItemView.js
Normal file
19
UI/Series/Details/EpisodeItemView.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
define(['app', 'Series/SeasonModel'], function () {
|
||||
|
||||
NzbDrone.Series.Details.EpisodeItemView = Backbone.Marionette.ItemView.extend({
|
||||
template: 'Series/Details/EpisodeItemTemplate',
|
||||
tagName: 'tr',
|
||||
|
||||
ui: {
|
||||
|
||||
},
|
||||
|
||||
events: {
|
||||
|
||||
},
|
||||
onRender: function () {
|
||||
NzbDrone.ModelBinder.bind(this.model, this.el);
|
||||
}
|
||||
});
|
||||
});
|
15
UI/Series/Details/SeasonCompositeTemplate.html
Normal file
15
UI/Series/Details/SeasonCompositeTemplate.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<h3>{{seasonTitle}}</h3>
|
||||
<table class="table table-hover x-season-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Title</th>
|
||||
<th>Air Date</th>
|
||||
<th>Quality</th>
|
||||
<th>Controls</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="x-episodes">
|
||||
|
||||
</tbody>
|
||||
</table>
|
16
UI/Series/Details/SeasonCompositeView.js
Normal file
16
UI/Series/Details/SeasonCompositeView.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
'use strict';
|
||||
define(['app', 'Series/Details/EpisodeItemView'], function () {
|
||||
NzbDrone.Series.Details.SeasonCompositeView = Backbone.Marionette.CompositeView.extend({
|
||||
itemView: NzbDrone.Series.Details.EpisodeItemView,
|
||||
itemViewContainer: '.x-episodes',
|
||||
template: 'Series/Details/SeasonCompositeTemplate',
|
||||
|
||||
initialize: function() {
|
||||
this.collection =new NzbDrone.Series.EpisodeCollection();
|
||||
this.collection.fetch({data: {
|
||||
seriesId: this.model.get('seriesId'),
|
||||
seasonNumber:this.model.get('seasonNumber')
|
||||
}});
|
||||
}
|
||||
});
|
||||
});
|
6
UI/Series/Details/SeriesDetailsTemplate.html
Normal file
6
UI/Series/Details/SeriesDetailsTemplate.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<div>
|
||||
<div class="x-series-details">
|
||||
{{overview}}
|
||||
</div>
|
||||
<div class="x-series-seasons"></div>
|
||||
</div>
|
13
UI/Series/Details/SeriesDetailsView.js
Normal file
13
UI/Series/Details/SeriesDetailsView.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
define(['app', 'Quality/QualityProfileCollection', 'Series/Details/SeasonCompositeView', 'Series/SeasonCollection'], function () {
|
||||
NzbDrone.Series.Details.SeriesDetailsView = Backbone.Marionette.CompositeView.extend({
|
||||
|
||||
itemView: NzbDrone.Series.Details.SeasonCompositeView,
|
||||
itemViewContainer: '.x-series-seasons',
|
||||
template: 'Series/Details/SeriesDetailsTemplate',
|
||||
|
||||
initialize: function () {
|
||||
this.collection = new NzbDrone.Series.SeasonCollection();
|
||||
this.collection.fetch({data: { seriesId: this.model.get('id') }});
|
||||
}
|
||||
});
|
||||
});
|
86
UI/Series/Edit/EditSeriesTemplate.html
Normal file
86
UI/Series/Edit/EditSeriesTemplate.html
Normal file
|
@ -0,0 +1,86 @@
|
|||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Edit: {{title}}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-horizontal">
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Monitored</label>
|
||||
<div class="controls">
|
||||
<div class="switch">
|
||||
<input type="checkbox" name="monitored" />
|
||||
</div>
|
||||
<span class="help-inline-checkbox">
|
||||
<i class="icon-question-sign" title="Should NzbDrone download episodes for this series?"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Use Season Folder</label>
|
||||
<div class="controls">
|
||||
<div class="switch">
|
||||
<input type="checkbox" name="seasonFolder" />
|
||||
</div>
|
||||
<span class="help-inline-checkbox">
|
||||
<i class="icon-question-sign" title="Should downloaded episodes be stored in season folders?"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputQualityProfile">Quality Profile</label>
|
||||
<div class="controls">
|
||||
|
||||
<select class="x-quality-profile" id="inputQualityProfile" name="qualityProfileId">
|
||||
{{#each qualityProfiles.models}}
|
||||
<option value="{{id}}">{{attributes.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
<span class="help-inline">
|
||||
<i class="icon-question-sign" title="Which Quality Profile should NzbDrone use to download episodes?"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputPath">Path</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="inputPath" placeholder="Path" name="path">
|
||||
<span class="help-inline">
|
||||
<i class="icon-question-sign" title="Where should NzbDrone store episodes for this series?"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputBacklogSetting">Backlog Setting</label>
|
||||
<div class="controls">
|
||||
<select id="inputBacklogSetting" class="inputClass x-backlog-setting" name="backlogSetting">
|
||||
<option value="0">Inherit</option>
|
||||
<option value="1">Enable</option>
|
||||
<option value="2">Disable</option>
|
||||
</select>
|
||||
<span class="help-inline">
|
||||
<i class="icon-question-sign" title="Should NzbDrone search for missing episodes every 30 days?"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputCustomStartDate">Custom Start Date</label>
|
||||
<div class="controls">
|
||||
<input type="date" id="inputCustomStartDate" name="customStartDate">
|
||||
<span class="help-inline">
|
||||
<i class="icon-question-sign" title="Should NzbDrone only download episodes after your preferred start date?"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-danger pull-left x-remove" >delete</button>
|
||||
<button class="btn" data-dismiss="modal">cancel</button>
|
||||
<button class="btn btn-primary x-save">save</button>
|
||||
</div>
|
46
UI/Series/Edit/EditSeriesView.js
Normal file
46
UI/Series/Edit/EditSeriesView.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
'use strict';
|
||||
define(['app', 'Series/SeriesModel', 'Series/Delete/DeleteSeriesView', 'Quality/QualityProfileCollection'], function () {
|
||||
|
||||
NzbDrone.Series.Edit.EditSeriesView = Backbone.Marionette.ItemView.extend({
|
||||
template: 'Series/Edit/EditSeriesTemplate',
|
||||
tagName: 'div',
|
||||
className: "modal",
|
||||
|
||||
ui: {
|
||||
progressbar: '.progress .bar',
|
||||
qualityProfile: '.x-quality-profile',
|
||||
backlogSettings: '.x-backlog-setting',
|
||||
switch: '.switch'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-save': 'saveSeries',
|
||||
'click .x-remove': 'removeSeries'
|
||||
},
|
||||
|
||||
onRender: function () {
|
||||
NzbDrone.ModelBinder.bind(this.model, this.el);
|
||||
this.ui.switch.bootstrapSwitch();
|
||||
},
|
||||
|
||||
|
||||
saveSeries: function () {
|
||||
//Todo: Get qualityProfile + backlog setting from UI
|
||||
var qualityProfile = this.ui.qualityProfile.val();
|
||||
var qualityProfileText = this.ui.qualityProfile.children('option:selected').text();
|
||||
var backlogSetting = this.ui.backlogSettings.val();
|
||||
|
||||
this.model.set({ qualityProfileId: qualityProfile, backlogSetting: backlogSetting, qualityProfileName: qualityProfileText });
|
||||
|
||||
this.model.save();
|
||||
this.trigger('saved');
|
||||
this.$el.parent().modal('hide');
|
||||
},
|
||||
|
||||
removeSeries: function () {
|
||||
var view = new NzbDrone.Series.Delete.DeleteSeriesView({ model: this.model });
|
||||
NzbDrone.modalRegion.show(view);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
6
UI/Series/EpisodeCollection.js
Normal file
6
UI/Series/EpisodeCollection.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
define(['app', 'Series/EpisodeModel'], function () {
|
||||
NzbDrone.Series.EpisodeCollection = Backbone.Collection.extend({
|
||||
url: NzbDrone.Constants.ApiRoot + '/episodes',
|
||||
model: NzbDrone.Series.EpisodeModel
|
||||
});
|
||||
});
|
12
UI/Series/EpisodeModel.js
Normal file
12
UI/Series/EpisodeModel.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
define(['app'], function () {
|
||||
NzbDrone.Series.EpisodeModel = Backbone.Model.extend({
|
||||
|
||||
mutators: {
|
||||
|
||||
},
|
||||
|
||||
defaults: {
|
||||
seasonNumber: 0
|
||||
}
|
||||
});
|
||||
});
|
1
UI/Series/Index/EmptySeriesIndexTemplate.html
Normal file
1
UI/Series/Index/EmptySeriesIndexTemplate.html
Normal file
|
@ -0,0 +1 @@
|
|||
<td colspan="8">No series found</td>
|
94
UI/Series/Index/SeriesIndexCollectionView.js
Normal file
94
UI/Series/Index/SeriesIndexCollectionView.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
'use strict';
|
||||
|
||||
define(['app', 'Quality/QualityProfileCollection', 'Series/Index/SeriesItemView'], function (app, qualityProfileCollection) {
|
||||
NzbDrone.Series.Index.SeriesIndexCollectionView = Backbone.Marionette.CompositeView.extend({
|
||||
itemView: NzbDrone.Series.Index.SeriesItemView,
|
||||
itemViewContainer: 'tbody',
|
||||
template: 'Series/Index/SeriesIndexTemplate',
|
||||
qualityProfileCollection: qualityProfileCollection,
|
||||
//emptyView: NzbDrone.Series.EmptySeriesCollectionView,
|
||||
|
||||
initialize: function () {
|
||||
this.collection = new NzbDrone.Series.SeriesCollection();
|
||||
//Todo: This caused the onRendered event to be trigger twice, which displays two empty collection messages
|
||||
//http://stackoverflow.com/questions/13065176/backbone-marionette-composit-view-onrender-executing-twice
|
||||
this.collection.fetch();
|
||||
this.qualityProfileCollection.fetch();
|
||||
|
||||
this.itemViewOptions = { qualityProfiles: this.qualityProfileCollection };
|
||||
},
|
||||
|
||||
ui:{
|
||||
table : '.x-series-table'
|
||||
},
|
||||
|
||||
onItemRemoved: function()
|
||||
{
|
||||
this.ui.table.trigger('update');
|
||||
},
|
||||
|
||||
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: [[1,0]],
|
||||
headers: {
|
||||
0: {
|
||||
sorter: 'title'
|
||||
},
|
||||
1: {
|
||||
sorter: 'innerHtml'
|
||||
},
|
||||
5: {
|
||||
sorter: 'date'
|
||||
},
|
||||
6: {
|
||||
sorter: false
|
||||
},
|
||||
7: {
|
||||
sorter: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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('<i class="icon-sort-up pull-right">');
|
||||
|
||||
else if ($(this).hasClass('tablesorter-headerAsc'))
|
||||
$(this).children('.tablesorter-header-inner').append('<i class="icon-sort-down pull-right">');
|
||||
|
||||
else if (!$(this).hasClass('sorter-false'))
|
||||
$(this).children('.tablesorter-header-inner').append('<i class="icon-sort pull-right">');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
NzbDrone.Series.Index.EmptySeriesCollectionView = Backbone.Marionette.CompositeView.extend({
|
||||
template: 'Series/Index/EmptySeriesCollectionTemplate',
|
||||
tagName: 'tr'
|
||||
});
|
15
UI/Series/Index/SeriesIndexTemplate.html
Normal file
15
UI/Series/Index/SeriesIndexTemplate.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<table class="table table-hover x-series-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th title="Status"></th>
|
||||
<th>Title</th>
|
||||
<th>Seasons</th>
|
||||
<th>Quality</th>
|
||||
<th>Network</th>
|
||||
<th>Next Airing</th>
|
||||
<th>Episodes</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
17
UI/Series/Index/SeriesItemTemplate.html
Normal file
17
UI/Series/Index/SeriesItemTemplate.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<td>{{{formatStatus status monitored}}}</td>
|
||||
<td><a href="/series/details/{{id}}">{{title}}</a></td>
|
||||
<td name="seasonCount"></td>
|
||||
<td name="qualityProfileName"></td>
|
||||
<td name="network"></td>
|
||||
<!-- If only DT could access the backbone model -->
|
||||
<td><span title="{{formatedDateString}}" data-date="{{nextAiring}}">{{bestDateString}}</span></td>
|
||||
<td>
|
||||
<div class="progress">
|
||||
<span class="progressbar-back-text">{{episodeFileCount}} / {{episodeCount}}</span>
|
||||
<div class="bar" style="width:{{percentOfEpisodes}}%"><span class="progressbar-front-text">{{episodeFileCount}} / {{episodeCount}}</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="icon-cog x-edit" title="Edit Series"></i>
|
||||
<i class="icon-remove x-remove" title="Delete Series"></i>
|
||||
</td>
|
48
UI/Series/Index/SeriesItemView.js
Normal file
48
UI/Series/Index/SeriesItemView.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
'use strict';
|
||||
|
||||
define([
|
||||
'app',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Series/SeriesCollection',
|
||||
'Series/Edit/EditSeriesView',
|
||||
'Series/Delete/DeleteSeriesView'
|
||||
|
||||
], function () {
|
||||
|
||||
NzbDrone.Series.Index.SeriesItemView = Backbone.Marionette.ItemView.extend({
|
||||
template: 'Series/Index/SeriesItemTemplate',
|
||||
tagName: 'tr',
|
||||
|
||||
ui: {
|
||||
'progressbar': '.progress .bar'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-edit': 'editSeries',
|
||||
'click .x-remove': 'removeSeries'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.qualityProfileCollection = options.qualityProfiles;
|
||||
},
|
||||
|
||||
onRender: function () {
|
||||
NzbDrone.ModelBinder.bind(this.model, this.el);
|
||||
},
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
6
UI/Series/SeasonCollection.js
Normal file
6
UI/Series/SeasonCollection.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
define(['app','Series/SeasonModel'], function () {
|
||||
NzbDrone.Series.SeasonCollection = Backbone.Collection.extend({
|
||||
url: NzbDrone.Constants.ApiRoot + '/season',
|
||||
model: NzbDrone.Series.SeasonModel
|
||||
});
|
||||
});
|
21
UI/Series/SeasonModel.js
Normal file
21
UI/Series/SeasonModel.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
define(['app'], function () {
|
||||
NzbDrone.Series.SeasonModel = Backbone.Model.extend({
|
||||
|
||||
mutators: {
|
||||
seasonTitle: function () {
|
||||
var seasonNumber = this.get('seasonNumber');
|
||||
|
||||
if (seasonNumber === 0) {
|
||||
return "Specials"
|
||||
}
|
||||
|
||||
return "Season " + seasonNumber;
|
||||
}
|
||||
},
|
||||
|
||||
defaults: {
|
||||
seasonNumber: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
|
6
UI/Series/SeriesCollection.js
Normal file
6
UI/Series/SeriesCollection.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
define(['app', 'Series/SeriesModel'], function () {
|
||||
NzbDrone.Series.SeriesCollection = Backbone.Collection.extend({
|
||||
url: NzbDrone.Constants.ApiRoot + '/series',
|
||||
model: NzbDrone.Series.SeriesModel
|
||||
});
|
||||
});
|
31
UI/Series/SeriesModel.js
Normal file
31
UI/Series/SeriesModel.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
define(['app', 'Quality/QualityProfileCollection'], function (app, qualityProfileCollection) {
|
||||
NzbDrone.Series.SeriesModel = Backbone.Model.extend({
|
||||
|
||||
urlRoot: NzbDrone.Constants.ApiRoot + '/series',
|
||||
|
||||
mutators: {
|
||||
bestDateString: function () {
|
||||
return bestDateString(this.get('nextAiring'));
|
||||
},
|
||||
|
||||
percentOfEpisodes: function () {
|
||||
var episodeCount = this.get('episodeCount');
|
||||
var episodeFileCount = this.get('episodeFileCount');
|
||||
|
||||
var percent = 100;
|
||||
|
||||
if (episodeCount > 0)
|
||||
percent = episodeFileCount / episodeCount * 100;
|
||||
|
||||
return percent;
|
||||
}
|
||||
},
|
||||
|
||||
defaults: {
|
||||
episodeFileCount: 0,
|
||||
episodeCount: 0,
|
||||
qualityProfiles: qualityProfileCollection
|
||||
}
|
||||
});
|
||||
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue