mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2026-04-17 21:44:48 -04:00
Profiles
Indexes are created with the same uniqueness when copying a table New: Non-English episode support New: Renamed Quality Profiles to Profiles and made them more powerful New: Configurable wait time before grabbing a release to wait for a better quality
This commit is contained in:
@@ -7,7 +7,7 @@ define(
|
||||
'AddSeries/RootFolders/RootFolderLayout',
|
||||
'AddSeries/Existing/AddExistingSeriesCollectionView',
|
||||
'AddSeries/AddSeriesView',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Profile/ProfileCollection',
|
||||
'AddSeries/RootFolders/RootFolderCollection',
|
||||
'Series/SeriesCollection'
|
||||
], function (vent,
|
||||
@@ -16,7 +16,7 @@ define(
|
||||
RootFolderLayout,
|
||||
ExistingSeriesCollectionView,
|
||||
AddSeriesView,
|
||||
QualityProfileCollection,
|
||||
ProfileCollection,
|
||||
RootFolderCollection) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
@@ -36,7 +36,7 @@ define(
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
QualityProfileCollection.fetch();
|
||||
ProfileCollection.fetch();
|
||||
RootFolderCollection.fetch()
|
||||
.done(function () {
|
||||
RootFolderCollection.synced = true;
|
||||
|
||||
@@ -6,7 +6,7 @@ define(
|
||||
'AppLayout',
|
||||
'backbone',
|
||||
'marionette',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Profile/ProfileCollection',
|
||||
'AddSeries/RootFolders/RootFolderCollection',
|
||||
'AddSeries/RootFolders/RootFolderLayout',
|
||||
'Series/SeriesCollection',
|
||||
@@ -19,7 +19,7 @@ define(
|
||||
AppLayout,
|
||||
Backbone,
|
||||
Marionette,
|
||||
QualityProfiles,
|
||||
Profiles,
|
||||
RootFolders,
|
||||
RootFolderLayout,
|
||||
SeriesCollection,
|
||||
@@ -32,7 +32,7 @@ define(
|
||||
template: 'AddSeries/SearchResultViewTemplate',
|
||||
|
||||
ui: {
|
||||
qualityProfile : '.x-quality-profile',
|
||||
profile : '.x-profile',
|
||||
rootFolder : '.x-root-folder',
|
||||
seasonFolder : '.x-season-folder',
|
||||
seriesType : '.x-series-type',
|
||||
@@ -42,11 +42,11 @@ define(
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-add' : '_addSeries',
|
||||
'change .x-quality-profile' : '_qualityProfileChanged',
|
||||
'change .x-root-folder' : '_rootFolderChanged',
|
||||
'change .x-season-folder' : '_seasonFolderChanged',
|
||||
'change .x-series-type' : '_seriesTypeChanged'
|
||||
'click .x-add' : '_addSeries',
|
||||
'change .x-profile' : '_profileChanged',
|
||||
'change .x-root-folder' : '_rootFolderChanged',
|
||||
'change .x-season-folder' : '_seasonFolderChanged',
|
||||
'change .x-series-type' : '_seriesTypeChanged'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
@@ -65,13 +65,13 @@ define(
|
||||
|
||||
onRender: function () {
|
||||
|
||||
var defaultQuality = Config.getValue(Config.Keys.DefaultQualityProfileId);
|
||||
var defaultProfile = Config.getValue(Config.Keys.DefaultProfileId);
|
||||
var defaultRoot = Config.getValue(Config.Keys.DefaultRootFolderId);
|
||||
var useSeasonFolder = Config.getValueBoolean(Config.Keys.UseSeasonFolder, true);
|
||||
var defaultSeriesType = Config.getValueBoolean(Config.Keys.DefaultSeriesType, true);
|
||||
|
||||
if (QualityProfiles.get(defaultQuality)) {
|
||||
this.ui.qualityProfile.val(defaultQuality);
|
||||
if (Profiles.get(defaultProfile)) {
|
||||
this.ui.profile.val(defaultProfile);
|
||||
}
|
||||
|
||||
if (RootFolders.get(defaultRoot)) {
|
||||
@@ -101,7 +101,7 @@ define(
|
||||
this.templateHelpers.existing = existingSeries[0].toJSON();
|
||||
}
|
||||
|
||||
this.templateHelpers.qualityProfiles = QualityProfiles.toJSON();
|
||||
this.templateHelpers.profiles = Profiles.toJSON();
|
||||
|
||||
if (!this.model.get('isExisting')) {
|
||||
this.templateHelpers.rootFolders = RootFolders.toJSON();
|
||||
@@ -109,8 +109,8 @@ define(
|
||||
},
|
||||
|
||||
_onConfigUpdated: function (options) {
|
||||
if (options.key === Config.Keys.DefaultQualityProfileId) {
|
||||
this.ui.qualityProfile.val(options.value);
|
||||
if (options.key === Config.Keys.DefaultProfileId) {
|
||||
this.ui.profile.val(options.value);
|
||||
}
|
||||
|
||||
else if (options.key === Config.Keys.DefaultRootFolderId) {
|
||||
@@ -126,8 +126,8 @@ define(
|
||||
}
|
||||
},
|
||||
|
||||
_qualityProfileChanged: function () {
|
||||
Config.setValue(Config.Keys.DefaultQualityProfileId, this.ui.qualityProfile.val());
|
||||
_profileChanged: function () {
|
||||
Config.setValue(Config.Keys.DefaultProfileId, this.ui.profile.val());
|
||||
},
|
||||
|
||||
_seasonFolderChanged: function () {
|
||||
@@ -160,14 +160,14 @@ define(
|
||||
var icon = this.ui.addButton.find('icon');
|
||||
icon.removeClass('icon-plus').addClass('icon-spin icon-spinner disabled');
|
||||
|
||||
var quality = this.ui.qualityProfile.val();
|
||||
var profile = this.ui.profile.val();
|
||||
var rootFolderPath = this.ui.rootFolder.children(':selected').text();
|
||||
var startingSeason = this.ui.startingSeason.val();
|
||||
var seriesType = this.ui.seriesType.val();
|
||||
var seasonFolder = this.ui.seasonFolder.prop('checked');
|
||||
|
||||
this.model.set({
|
||||
qualityProfileId: quality,
|
||||
profileId: profile,
|
||||
rootFolderPath: rootFolderPath,
|
||||
seasonFolder: seasonFolder,
|
||||
seriesType: seriesType
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label>Quality Profile</label>
|
||||
{{> QualityProfileSelectionPartial qualityProfiles}}
|
||||
<label>Profile</label>
|
||||
{{> ProfileSelectionPartial profiles}}
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
|
||||
@@ -4,8 +4,8 @@ define(
|
||||
'backgrid',
|
||||
'marionette',
|
||||
'underscore',
|
||||
'Settings/Quality/Profile/QualityProfileSchemaCollection',
|
||||
], function (Backgrid, Marionette, _, QualityProfileSchemaCollection) {
|
||||
'Settings/Profile/ProfileSchemaCollection'
|
||||
], function (Backgrid, Marionette, _, ProfileSchemaCollection) {
|
||||
return Backgrid.CellEditor.extend({
|
||||
|
||||
className: 'quality-cell-editor',
|
||||
@@ -21,12 +21,12 @@ define(
|
||||
render: function () {
|
||||
var self = this;
|
||||
|
||||
var qualityProfileSchemaCollection = new QualityProfileSchemaCollection();
|
||||
var promise = qualityProfileSchemaCollection.fetch();
|
||||
var profileSchemaCollection = new ProfileSchemaCollection();
|
||||
var promise = profileSchemaCollection.fetch();
|
||||
|
||||
promise.done(function () {
|
||||
var templateName = self.template;
|
||||
self.schema = qualityProfileSchemaCollection.first();
|
||||
self.schema = profileSchemaCollection.first();
|
||||
|
||||
var selected = _.find(self.schema.get('items'), function (model) {
|
||||
return model.quality.id === self.model.get(self.column.get('name')).quality.id;
|
||||
@@ -50,13 +50,13 @@ define(
|
||||
var column = this.column;
|
||||
var selected = parseInt(this.$el.val(), 10);
|
||||
|
||||
var qualityProfileItem = _.find(this.schema.get('items'), function(model) {
|
||||
var profileItem = _.find(this.schema.get('items'), function(model) {
|
||||
return model.quality.id === selected;
|
||||
});
|
||||
|
||||
var newQuality = {
|
||||
proper : false,
|
||||
quality: qualityProfileItem.quality
|
||||
quality: profileItem.quality
|
||||
};
|
||||
|
||||
model.set(column.get('name'), newQuality);
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
define(
|
||||
[
|
||||
'backgrid',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Profile/ProfileCollection',
|
||||
'underscore'
|
||||
], function (Backgrid, QualityProfileCollection,_) {
|
||||
], function (Backgrid, ProfileCollection,_) {
|
||||
return Backgrid.Cell.extend({
|
||||
className: 'quality-profile-cell',
|
||||
className: 'profile-cell',
|
||||
|
||||
render: function () {
|
||||
|
||||
this.$el.empty();
|
||||
var qualityProfileId = this.model.get(this.column.get('name'));
|
||||
var profileId = this.model.get(this.column.get('name'));
|
||||
|
||||
var profile = _.findWhere(QualityProfileCollection.models, { id: qualityProfileId });
|
||||
var profile = _.findWhere(ProfileCollection.models, { id: profileId });
|
||||
|
||||
if (profile) {
|
||||
this.$el.html(profile.get('name'));
|
||||
@@ -8,7 +8,7 @@ define(
|
||||
ConfigUpdatedEvent: 'ConfigUpdatedEvent'
|
||||
},
|
||||
Keys : {
|
||||
DefaultQualityProfileId : 'DefaultQualityProfileId',
|
||||
DefaultProfileId : 'DefaultProfileId',
|
||||
DefaultRootFolderId : 'DefaultRootFolderId',
|
||||
UseSeasonFolder : 'UseSeasonFolder',
|
||||
DefaultSeriesType : 'DefaultSeriesType',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="episode-info">
|
||||
{{#with series}}
|
||||
{{qualityProfile qualityProfileId}}
|
||||
{{profile profileId}}
|
||||
<span class="label label-info">{{network}}</span>
|
||||
{{/with}}
|
||||
<span class="label label-info">{{StartTime airDateUtc}}</span>
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
define(
|
||||
[
|
||||
'handlebars',
|
||||
'Quality/QualityProfileCollection'
|
||||
], function (Handlebars, QualityProfileCollection) {
|
||||
'Profile/ProfileCollection'
|
||||
], function (Handlebars, ProfileCollection) {
|
||||
|
||||
Handlebars.registerHelper('qualityProfile', function (profileId) {
|
||||
Handlebars.registerHelper('profile', function (profileId) {
|
||||
|
||||
var profile = QualityProfileCollection.get(profileId);
|
||||
var profile = ProfileCollection.get(profileId);
|
||||
|
||||
if (profile) {
|
||||
return new Handlebars.SafeString('<span class="label label-default quality-profile-label">' + profile.get('name') + '</span>');
|
||||
return new Handlebars.SafeString('<span class="label label-default profile-label">' + profile.get("name") + '</span>');
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
9
src/UI/Handlebars/Helpers/String.js
Normal file
9
src/UI/Handlebars/Helpers/String.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'handlebars'
|
||||
], function (Handlebars) {
|
||||
Handlebars.registerHelper('TitleCase', function (input) {
|
||||
return new Handlebars.SafeString(input.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}));
|
||||
});
|
||||
});
|
||||
@@ -11,7 +11,7 @@ define(
|
||||
'Handlebars/Helpers/Quality',
|
||||
'Handlebars/Helpers/System',
|
||||
'Handlebars/Helpers/EachReverse',
|
||||
'Handlebars/Helpers/EachReverse',
|
||||
'Handlebars/Helpers/String',
|
||||
'Handlebars/Handlebars.Debug'
|
||||
], function (Templates) {
|
||||
return function () {
|
||||
|
||||
@@ -31,6 +31,11 @@ define(
|
||||
icon = 'icon-inbox';
|
||||
title = 'Downloaded';
|
||||
}
|
||||
|
||||
if (status === 'pending') {
|
||||
icon = 'icon-time';
|
||||
title = 'Pending';
|
||||
}
|
||||
|
||||
if (errorMessage !== '') {
|
||||
if (status === 'completed') {
|
||||
|
||||
@@ -14,12 +14,21 @@ define(
|
||||
|
||||
if (this.cellValue) {
|
||||
|
||||
//If the release is pending we want to use the timeleft as the time it will be processed at
|
||||
if (this.cellValue.get('status').toLowerCase() === 'pending') {
|
||||
this.$el.html('-');
|
||||
this.$el.attr('title', 'Will be processed again in: {0}'.format(this.cellValue.get('timeleft')));
|
||||
this.$el.attr('data-container', 'body');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
var timeleft = this.cellValue.get('timeleft');
|
||||
var totalSize = fileSize(this.cellValue.get('size'), 1, false);
|
||||
var remainingSize = fileSize(this.cellValue.get('sizeleft'), 1, false);
|
||||
|
||||
if (timeleft === undefined) {
|
||||
this.$el.html("-");
|
||||
this.$el.html('-');
|
||||
}
|
||||
else {
|
||||
this.$el.html('<span title="{1} / {2}">{0}</span>'.format(timeleft, remainingSize, totalSize));
|
||||
|
||||
18
src/UI/Profile/ProfileCollection.js
Normal file
18
src/UI/Profile/ProfileCollection.js
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'Profile/ProfileModel'
|
||||
], function (Backbone, ProfileModel) {
|
||||
|
||||
var ProfileCollection = Backbone.Collection.extend({
|
||||
model: ProfileModel,
|
||||
url : window.NzbDrone.ApiRoot + '/profile'
|
||||
});
|
||||
|
||||
var profiles = new ProfileCollection();
|
||||
|
||||
profiles.fetch();
|
||||
|
||||
return profiles;
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
<select class="col-md-2 form-control x-quality-profile">
|
||||
<select class="col-md-2 form-control x-profile">
|
||||
{{#each this}}
|
||||
<option value="{{id}}">{{name}}</option>
|
||||
{{/each}}
|
||||
@@ -1,18 +0,0 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'Quality/QualityProfileModel'
|
||||
], function (Backbone, QualityProfileModel) {
|
||||
|
||||
var QualityProfileCollection = Backbone.Collection.extend({
|
||||
model: QualityProfileModel,
|
||||
url : window.NzbDrone.ApiRoot + '/qualityprofile'
|
||||
});
|
||||
|
||||
var profiles = new QualityProfileCollection();
|
||||
|
||||
profiles.fetch();
|
||||
|
||||
return profiles;
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
{{qualityProfile qualityProfileId}}
|
||||
{{profile profileId}}
|
||||
<span class="label label-info">{{network}}</span>
|
||||
<span class="label label-info">{{runtime}} minutes</span>
|
||||
<span class="label label-info">{{path}}</span>
|
||||
|
||||
@@ -3,17 +3,17 @@ define(
|
||||
[
|
||||
'vent',
|
||||
'marionette',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Profile/ProfileCollection',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Mixins/AsValidatedView',
|
||||
'Mixins/AutoComplete'
|
||||
], function (vent, Marionette, QualityProfiles, AsModelBoundView, AsValidatedView) {
|
||||
], function (vent, Marionette, Profiles, AsModelBoundView, AsValidatedView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Series/Edit/EditSeriesViewTemplate',
|
||||
|
||||
ui: {
|
||||
qualityProfile: '.x-quality-profile',
|
||||
profile: '.x-profile',
|
||||
path : '.x-path'
|
||||
},
|
||||
|
||||
@@ -24,14 +24,14 @@ define(
|
||||
|
||||
|
||||
initialize: function () {
|
||||
this.model.set('qualityProfiles', QualityProfiles);
|
||||
this.model.set('profiles', Profiles);
|
||||
},
|
||||
|
||||
_saveSeries: function () {
|
||||
|
||||
var self = this;
|
||||
var qualityProfileId = this.ui.qualityProfile.val();
|
||||
this.model.set({ qualityProfileId: qualityProfileId});
|
||||
var profileId = this.ui.profile.val();
|
||||
this.model.set({ profileId: profileId});
|
||||
|
||||
this.model.save().done(function () {
|
||||
self.trigger('saved');
|
||||
|
||||
@@ -58,11 +58,11 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">Quality Profile</label>
|
||||
<label class="col-sm-4 control-label">Profile</label>
|
||||
|
||||
<div class="col-sm-4">
|
||||
<select class="form-control x-quality-profile" name="qualityProfileId">
|
||||
{{#each qualityProfiles.models}}
|
||||
<select class="form-control x-profile" id="inputProfile" name="profileId">
|
||||
{{#each profiles.models}}
|
||||
<option value="{{id}}">{{attributes.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
|
||||
@@ -5,7 +5,7 @@ define(
|
||||
'marionette',
|
||||
'backgrid',
|
||||
'vent',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Profile/ProfileCollection',
|
||||
'AddSeries/RootFolders/RootFolderCollection',
|
||||
'Shared/Toolbar/ToolbarLayout',
|
||||
'AddSeries/RootFolders/RootFolderLayout',
|
||||
@@ -15,7 +15,7 @@ define(
|
||||
Marionette,
|
||||
Backgrid,
|
||||
vent,
|
||||
QualityProfiles,
|
||||
Profiles,
|
||||
RootFolders,
|
||||
ToolbarLayout,
|
||||
RootFolderLayout,
|
||||
@@ -26,7 +26,7 @@ define(
|
||||
|
||||
ui: {
|
||||
monitored : '.x-monitored',
|
||||
qualityProfile : '.x-quality-profiles',
|
||||
profile : '.x-profiles',
|
||||
seasonFolder : '.x-season-folder',
|
||||
rootFolder : '.x-root-folder',
|
||||
selectedCount : '.x-selected-count',
|
||||
@@ -43,8 +43,8 @@ define(
|
||||
|
||||
templateHelpers: function () {
|
||||
return {
|
||||
qualityProfiles: QualityProfiles,
|
||||
rootFolders : RootFolders.toJSON()
|
||||
profiles : Profiles,
|
||||
rootFolders: RootFolders.toJSON()
|
||||
};
|
||||
},
|
||||
|
||||
@@ -68,7 +68,7 @@ define(
|
||||
var selected = this.editorGrid.getSelectedModels();
|
||||
|
||||
var monitored = this.ui.monitored.val();
|
||||
var profile = this.ui.qualityProfile.val();
|
||||
var profile = this.ui.profile.val();
|
||||
var seasonFolder = this.ui.seasonFolder.val();
|
||||
var rootFolder = this.ui.rootFolder.val();
|
||||
|
||||
@@ -82,7 +82,7 @@ define(
|
||||
}
|
||||
|
||||
if (profile !== 'noChange') {
|
||||
model.set('qualityProfileId', parseInt(profile, 10));
|
||||
model.set('profileId', parseInt(profile, 10));
|
||||
}
|
||||
|
||||
if (seasonFolder === 'true') {
|
||||
@@ -113,7 +113,7 @@ define(
|
||||
|
||||
if (selectedCount === 0) {
|
||||
this.ui.monitored.attr('disabled', '');
|
||||
this.ui.qualityProfile.attr('disabled', '');
|
||||
this.ui.profile.attr('disabled', '');
|
||||
this.ui.seasonFolder.attr('disabled', '');
|
||||
this.ui.rootFolder.attr('disabled', '');
|
||||
this.ui.saveButton.attr('disabled', '');
|
||||
@@ -122,7 +122,7 @@ define(
|
||||
|
||||
else {
|
||||
this.ui.monitored.removeAttr('disabled', '');
|
||||
this.ui.qualityProfile.removeAttr('disabled', '');
|
||||
this.ui.profile.removeAttr('disabled', '');
|
||||
this.ui.seasonFolder.removeAttr('disabled', '');
|
||||
this.ui.rootFolder.removeAttr('disabled', '');
|
||||
this.ui.saveButton.removeAttr('disabled', '');
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label>Quality Profile</label>
|
||||
<label>Profile</label>
|
||||
|
||||
<select class="form-control x-quality-profiles">
|
||||
<select class="form-control x-profiles">
|
||||
<option value="noChange">No change</option>
|
||||
{{#each qualityProfiles.models}}
|
||||
{{#each profiles.models}}
|
||||
<option value="{{id}}">{{attributes.name}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
|
||||
@@ -7,7 +7,7 @@ define(
|
||||
'Series/Index/EmptyView',
|
||||
'Series/SeriesCollection',
|
||||
'Cells/SeriesTitleCell',
|
||||
'Cells/QualityProfileCell',
|
||||
'Cells/ProfileCell',
|
||||
'Cells/SeriesStatusCell',
|
||||
'Cells/SeasonFolderCell',
|
||||
'Shared/Toolbar/ToolbarLayout',
|
||||
@@ -19,7 +19,7 @@ define(
|
||||
EmptyView,
|
||||
SeriesCollection,
|
||||
SeriesTitleCell,
|
||||
QualityProfileCell,
|
||||
ProfileCell,
|
||||
SeriesStatusCell,
|
||||
SeasonFolderCell,
|
||||
ToolbarLayout,
|
||||
@@ -33,10 +33,10 @@ define(
|
||||
},
|
||||
|
||||
ui: {
|
||||
monitored : '.x-monitored',
|
||||
qualityProfiles: '.x-quality-profiles',
|
||||
rootFolder : '.x-root-folder',
|
||||
selectedCount : '.x-selected-count'
|
||||
monitored : '.x-monitored',
|
||||
profiles : '.x-profiles',
|
||||
rootFolder : '.x-root-folder',
|
||||
selectedCount : '.x-selected-count'
|
||||
},
|
||||
|
||||
events: {
|
||||
@@ -47,36 +47,36 @@ define(
|
||||
columns:
|
||||
[
|
||||
{
|
||||
name : '',
|
||||
cell : 'select-row',
|
||||
headerCell: 'select-all',
|
||||
sortable : false
|
||||
name : '',
|
||||
cell : 'select-row',
|
||||
headerCell : 'select-all',
|
||||
sortable : false
|
||||
},
|
||||
{
|
||||
name : 'statusWeight',
|
||||
label : '',
|
||||
cell : SeriesStatusCell
|
||||
name : 'statusWeight',
|
||||
label : '',
|
||||
cell : SeriesStatusCell
|
||||
},
|
||||
{
|
||||
name : 'title',
|
||||
label : 'Title',
|
||||
cell : SeriesTitleCell,
|
||||
cellValue : 'this'
|
||||
name : 'title',
|
||||
label : 'Title',
|
||||
cell : SeriesTitleCell,
|
||||
cellValue : 'this'
|
||||
},
|
||||
{
|
||||
name : 'qualityProfileId',
|
||||
label : 'Quality',
|
||||
cell : QualityProfileCell
|
||||
name : 'profileId',
|
||||
label : 'Profile',
|
||||
cell : ProfileCell
|
||||
},
|
||||
{
|
||||
name : 'seasonFolder',
|
||||
label : 'Season Folder',
|
||||
cell : SeasonFolderCell
|
||||
name : 'seasonFolder',
|
||||
label : 'Season Folder',
|
||||
cell : SeasonFolderCell
|
||||
},
|
||||
{
|
||||
name : 'path',
|
||||
label : 'Path',
|
||||
cell : 'string'
|
||||
name : 'path',
|
||||
label : 'Path',
|
||||
cell : 'string'
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
{{seasonCountHelper}}
|
||||
|
||||
{{qualityProfile qualityProfileId}}
|
||||
{{profile profileId}}
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-4">
|
||||
{{> EpisodeProgressPartial }}
|
||||
|
||||
@@ -11,7 +11,7 @@ define(
|
||||
'Cells/RelativeDateCell',
|
||||
'Cells/SeriesTitleCell',
|
||||
'Cells/TemplatedCell',
|
||||
'Cells/QualityProfileCell',
|
||||
'Cells/ProfileCell',
|
||||
'Cells/EpisodeProgressCell',
|
||||
'Cells/SeriesActionsCell',
|
||||
'Cells/SeriesStatusCell',
|
||||
@@ -29,7 +29,7 @@ define(
|
||||
RelativeDateCell,
|
||||
SeriesTitleCell,
|
||||
TemplatedCell,
|
||||
QualityProfileCell,
|
||||
ProfileCell,
|
||||
EpisodeProgressCell,
|
||||
SeriesActionsCell,
|
||||
SeriesStatusCell,
|
||||
@@ -65,9 +65,9 @@ define(
|
||||
cell : 'integer'
|
||||
},
|
||||
{
|
||||
name : 'qualityProfileId',
|
||||
label : 'Quality',
|
||||
cell : QualityProfileCell
|
||||
name : 'profileId',
|
||||
label: 'Profile',
|
||||
cell : ProfileCell
|
||||
},
|
||||
{
|
||||
name : 'network',
|
||||
@@ -165,7 +165,7 @@ define(
|
||||
},
|
||||
{
|
||||
title: 'Quality',
|
||||
name : 'qualityProfileId'
|
||||
name : 'profileId'
|
||||
},
|
||||
{
|
||||
title: 'Network',
|
||||
|
||||
@@ -7,6 +7,7 @@ define(
|
||||
Handlebars.registerHelper('allowedLabeler', function () {
|
||||
var ret = '';
|
||||
var cutoff = this.cutoff;
|
||||
|
||||
_.each(this.items, function (item) {
|
||||
if (item.allowed) {
|
||||
if (item.quality.id === cutoff.id) {
|
||||
@@ -6,7 +6,7 @@ define(
|
||||
], function (vent, Marionette) {
|
||||
|
||||
return Marionette.ItemView.extend({
|
||||
template: 'Settings/Quality/Profile/DeleteQualityProfileViewTemplate',
|
||||
template: 'Settings/Profile/DeleteProfileViewTemplate',
|
||||
|
||||
events: {
|
||||
'click .x-confirm-delete': '_removeProfile'
|
||||
@@ -4,6 +4,6 @@ define(
|
||||
'marionette'
|
||||
], function (Marionette) {
|
||||
return Marionette.ItemView.extend({
|
||||
template : 'Settings/Quality/Profile/Edit/EditQualityProfileItemViewTemplate'
|
||||
template : 'Settings/Profile/Edit/EditProfileItemViewTemplate'
|
||||
});
|
||||
});
|
||||
@@ -6,10 +6,10 @@ define(
|
||||
'AppLayout',
|
||||
'marionette',
|
||||
'backbone',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileItemView',
|
||||
'Settings/Quality/Profile/Edit/QualitySortableCollectionView',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileView',
|
||||
'Settings/Quality/Profile/DeleteQualityProfileView',
|
||||
'Settings/Profile/Edit/EditProfileItemView',
|
||||
'Settings/Profile/Edit/QualitySortableCollectionView',
|
||||
'Settings/Profile/Edit/EditProfileView',
|
||||
'Settings/Profile/DeleteProfileView',
|
||||
'Series/SeriesCollection',
|
||||
'Config'
|
||||
], function (_,
|
||||
@@ -17,15 +17,15 @@ define(
|
||||
AppLayout,
|
||||
Marionette,
|
||||
Backbone,
|
||||
EditQualityProfileItemView,
|
||||
EditProfileItemView,
|
||||
QualitySortableCollectionView,
|
||||
EditQualityProfileView,
|
||||
EditProfileView,
|
||||
DeleteView,
|
||||
SeriesCollection,
|
||||
Config) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Settings/Quality/Profile/Edit/EditQualityProfileLayoutTemplate',
|
||||
template: 'Settings/Profile/Edit/EditProfileLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
fields : '#x-fields',
|
||||
@@ -37,8 +37,8 @@ define(
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-save' : '_saveQualityProfile',
|
||||
'click .x-cancel' : '_cancelQualityProfile',
|
||||
'click .x-save' : '_saveProfile',
|
||||
'click .x-cancel' : '_cancelProfile',
|
||||
'click .x-delete' : '_delete'
|
||||
},
|
||||
|
||||
@@ -53,7 +53,7 @@ define(
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.fieldsView = new EditQualityProfileView({ model: this.model });
|
||||
this.fieldsView = new EditProfileView({ model: this.model });
|
||||
this._showFieldsView();
|
||||
|
||||
this.sortableListView = new QualitySortableCollectionView({
|
||||
@@ -94,7 +94,7 @@ define(
|
||||
this._showFieldsView();
|
||||
},
|
||||
|
||||
_saveQualityProfile: function () {
|
||||
_saveProfile: function () {
|
||||
var self = this;
|
||||
var cutoff = this.fieldsView.getCutoff();
|
||||
this.model.set('cutoff', cutoff);
|
||||
@@ -109,7 +109,7 @@ define(
|
||||
}
|
||||
},
|
||||
|
||||
_cancelQualityProfile: function () {
|
||||
_cancelProfile: function () {
|
||||
if (!this.model.has('id')) {
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
return;
|
||||
@@ -136,7 +136,7 @@ define(
|
||||
_updateDisableStatus: function () {
|
||||
if (this._isQualityInUse()) {
|
||||
this.ui.deleteButton.addClass('disabled');
|
||||
this.ui.deleteButton.attr('title', 'Can\'t delete quality profiles attached to a series.');
|
||||
this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a series.');
|
||||
}
|
||||
else {
|
||||
this.ui.deleteButton.removeClass('disabled');
|
||||
@@ -144,7 +144,7 @@ define(
|
||||
},
|
||||
|
||||
_isQualityInUse: function () {
|
||||
return SeriesCollection.where({'qualityProfileId': this.model.id}).length !== 0;
|
||||
return SeriesCollection.where({'profileId': this.model.id}).length !== 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
61
src/UI/Settings/Profile/Edit/EditProfileView.js
Normal file
61
src/UI/Settings/Profile/Edit/EditProfileView.js
Normal file
@@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'underscore',
|
||||
'marionette',
|
||||
'Settings/Profile/Language/LanguageCollection',
|
||||
'Config',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Mixins/AsValidatedView'
|
||||
], function (_, Marionette, LanguageCollection, Config, AsModelBoundView, AsValidatedView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Settings/Profile/Edit/EditProfileViewTemplate',
|
||||
|
||||
ui: {
|
||||
cutoff : '.x-cutoff',
|
||||
delay : '.x-delay',
|
||||
delayMode : '.x-delay-mode'
|
||||
},
|
||||
|
||||
events: {
|
||||
'change .x-delay': 'toggleDelayMode',
|
||||
'keyup .x-delay': 'toggleDelayMode'
|
||||
},
|
||||
|
||||
templateHelpers: function () {
|
||||
return {
|
||||
languages : LanguageCollection.toJSON()
|
||||
};
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.toggleDelayMode();
|
||||
},
|
||||
|
||||
getCutoff: function () {
|
||||
var self = this;
|
||||
|
||||
return _.findWhere(_.pluck(this.model.get('items'), 'quality'), { id: parseInt(self.ui.cutoff.val(), 10)});
|
||||
},
|
||||
|
||||
toggleDelayMode: function () {
|
||||
var delay = parseInt(this.ui.delay.val(), 10);
|
||||
|
||||
if (isNaN(delay)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (delay > 0 && Config.getValueBoolean(Config.Keys.AdvancedSettings)) {
|
||||
this.ui.delayMode.show();
|
||||
}
|
||||
|
||||
else {
|
||||
this.ui.delayMode.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AsValidatedView.call(view);
|
||||
return AsModelBoundView.call(view);
|
||||
});
|
||||
71
src/UI/Settings/Profile/Edit/EditProfileViewTemplate.html
Normal file
71
src/UI/Settings/Profile/Edit/EditProfileViewTemplate.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<input type="text" name="name" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Language</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control" name="language">
|
||||
{{#each languages}}
|
||||
{{#unless_eq nameLower compare="unknown"}}
|
||||
<option value="{{nameLower}}">{{name}}</option>
|
||||
{{/unless_eq}}
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-nd-form-info" title="Series assigned this profile will be look for episodes with the selected language"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group advanced-setting">
|
||||
<label class="col-sm-3 control-label">Delay</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<input type="number" min="0" max="72" name="grabDelay" class="form-control x-delay">
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-nd-form-info" title="Wait time in hours before grabbing a release automatically, set to 0 to disable. The highest allowed quality in the profile will be grabbed immediately when available."/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group advanced-setting x-delay-mode">
|
||||
<label class="col-sm-3 control-label">Delay Mode</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control" name="grabDelayMode">
|
||||
<option value="first">First</option>
|
||||
<option value="cutoff">Cutoff</option>
|
||||
<option value="always">Always</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-nd-form-info" data-html="true" title="First: Delay until first wanted release passes delay, grabbing best quality release at that time. Cutoff: Delay for all qualities below the cutoff. Always: Delay before grabbing all qualities"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Cutoff</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control x-cutoff" name="cutoff.id" validation-name="cutoff">
|
||||
{{#eachReverse items}}
|
||||
{{#if allowed}}
|
||||
<option value="{{quality.id}}">{{quality.name}}</option>
|
||||
{{/if}}
|
||||
{{/eachReverse}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-nd-form-info" title="Once this quality is reached NzbDrone will no longer download episodes"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone.collectionview',
|
||||
'Settings/Profile/Edit/EditProfileItemView'
|
||||
], function (BackboneSortableCollectionView, EditProfileItemView) {
|
||||
return BackboneSortableCollectionView.extend({
|
||||
|
||||
className: 'qualities',
|
||||
modelView: EditProfileItemView,
|
||||
|
||||
attributes: {
|
||||
'validation-name': 'items'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click li, td' : '_listItem_onMousedown',
|
||||
'dblclick li, td' : '_listItem_onDoubleClick',
|
||||
'keydown' : '_onKeydown'
|
||||
}
|
||||
});
|
||||
});
|
||||
18
src/UI/Settings/Profile/Language/LanguageCollection.js
Normal file
18
src/UI/Settings/Profile/Language/LanguageCollection.js
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'Settings/Profile/Language/LanguageModel'
|
||||
], function (Backbone, LanguageModel) {
|
||||
|
||||
var LanuageCollection = Backbone.Collection.extend({
|
||||
model: LanguageModel,
|
||||
url : window.NzbDrone.ApiRoot + '/language'
|
||||
});
|
||||
|
||||
var languages = new LanuageCollection();
|
||||
|
||||
languages.fetch();
|
||||
|
||||
return languages;
|
||||
});
|
||||
10
src/UI/Settings/Profile/Language/LanguageModel.js
Normal file
10
src/UI/Settings/Profile/Language/LanguageModel.js
Normal file
@@ -0,0 +1,10 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone'
|
||||
], function (Backbone) {
|
||||
return Backbone.Model.extend({
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
20
src/UI/Settings/Profile/LanguageLabel.js
Normal file
20
src/UI/Settings/Profile/LanguageLabel.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'underscore',
|
||||
'handlebars',
|
||||
'Settings/Profile/Language/LanguageCollection'
|
||||
], function (_, Handlebars, LanguageCollection) {
|
||||
Handlebars.registerHelper('languageLabel', function () {
|
||||
|
||||
var wantedLanguage = this.language;
|
||||
|
||||
var language = LanguageCollection.find(function (lang) {
|
||||
return lang.get('nameLower') === wantedLanguage;
|
||||
});
|
||||
|
||||
var result = '<span class="label label-primary">' + language.get('name') + '</span>';
|
||||
|
||||
return new Handlebars.SafeString(result);
|
||||
});
|
||||
});
|
||||
@@ -1,10 +1,10 @@
|
||||
<fieldset>
|
||||
<legend>Quality Profiles</legend>
|
||||
<legend>Profiles</legend>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<ul class="quality-profiles thingies">
|
||||
<ul class="profiles thingies">
|
||||
<li>
|
||||
<div class="quality-profile-item thingy add-card x-add-card">
|
||||
<div class="profile-item thingy add-card x-add-card">
|
||||
<span class="center well">
|
||||
<i class="icon-plus" title="Add Profile"/>
|
||||
</span>
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
define(['AppLayout',
|
||||
'marionette',
|
||||
'Settings/Quality/Profile/QualityProfileView',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileLayout',
|
||||
'Settings/Quality/Profile/QualityProfileSchemaCollection',
|
||||
'Settings/Profile/ProfileView',
|
||||
'Settings/Profile/Edit/EditProfileLayout',
|
||||
'Settings/Profile/ProfileSchemaCollection',
|
||||
'underscore'
|
||||
], function (AppLayout, Marionette, QualityProfileView, EditProfileView, ProfileCollection, _) {
|
||||
], function (AppLayout, Marionette, ProfileView, EditProfileView, ProfileCollection, _) {
|
||||
|
||||
return Marionette.CompositeView.extend({
|
||||
itemView : QualityProfileView,
|
||||
itemViewContainer: '.quality-profiles',
|
||||
template : 'Settings/Quality/Profile/QualityProfileCollectionTemplate',
|
||||
itemView : ProfileView,
|
||||
itemViewContainer: '.profiles',
|
||||
template : 'Settings/Profile/ProfileCollectionTemplate',
|
||||
|
||||
ui: {
|
||||
'addCard': '.x-add-card'
|
||||
27
src/UI/Settings/Profile/ProfileLayout.js
Normal file
27
src/UI/Settings/Profile/ProfileLayout.js
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
define(
|
||||
[
|
||||
'marionette',
|
||||
'Profile/ProfileCollection',
|
||||
'Settings/Profile/ProfileCollectionView',
|
||||
'Settings/Profile/Language/LanguageCollection'
|
||||
], function (Marionette, ProfileCollection, ProfileCollectionView, LanguageCollection) {
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Settings/Profile/ProfileLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
profile : '#profile'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.settings = options.settings;
|
||||
ProfileCollection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.profile.show(new ProfileCollectionView({collection: ProfileCollection}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
3
src/UI/Settings/Profile/ProfileLayoutTemplate.html
Normal file
3
src/UI/Settings/Profile/ProfileLayoutTemplate.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12" id="profile"/>
|
||||
</div>
|
||||
13
src/UI/Settings/Profile/ProfileSchemaCollection.js
Normal file
13
src/UI/Settings/Profile/ProfileSchemaCollection.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'Profile/ProfileModel'
|
||||
], function (Backbone, ProfileModel) {
|
||||
|
||||
return Backbone.Collection.extend({
|
||||
model: ProfileModel,
|
||||
url : window.NzbDrone.ApiRoot + '/profile/schema'
|
||||
});
|
||||
});
|
||||
@@ -4,14 +4,15 @@ define(
|
||||
[
|
||||
'AppLayout',
|
||||
'marionette',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileLayout',
|
||||
'Settings/Profile/Edit/EditProfileLayout',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Settings/Quality/Profile/AllowedLabeler',
|
||||
'Settings/Profile/AllowedLabeler',
|
||||
'Settings/Profile/LanguageLabel',
|
||||
'bootstrap'
|
||||
], function (AppLayout, Marionette, EditProfileView, AsModelBoundView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Settings/Quality/Profile/QualityProfileViewTemplate',
|
||||
template: 'Settings/Profile/ProfileViewTemplate',
|
||||
tagName : 'li',
|
||||
|
||||
ui: {
|
||||
16
src/UI/Settings/Profile/ProfileViewTemplate.html
Normal file
16
src/UI/Settings/Profile/ProfileViewTemplate.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="profile-item thingy" title="Click to edit">
|
||||
<div>
|
||||
<h3 name="name"></h3>
|
||||
</div>
|
||||
|
||||
<div class="language">
|
||||
{{languageLabel}}
|
||||
|
||||
{{#if_gt grabDelay compare="0"}}
|
||||
<i class="icon-time" title="{{grabDelay}} hour, Mode: {{TitleCase grabDelayMode}}"></i>
|
||||
{{/if_gt}}
|
||||
</div>
|
||||
<ul class="allowed-qualities">
|
||||
{{allowedLabeler}}
|
||||
</ul>
|
||||
</div>
|
||||
31
src/UI/Settings/Profile/profile.less
Normal file
31
src/UI/Settings/Profile/profile.less
Normal file
@@ -0,0 +1,31 @@
|
||||
@import "../../Content/Bootstrap/mixins";
|
||||
@import "../../Content/FontAwesome/font-awesome";
|
||||
@import "../../Shared/Styles/clickable.less";
|
||||
|
||||
.profile-item {
|
||||
.clickable;
|
||||
|
||||
width: 300px;
|
||||
height: 158px;
|
||||
padding: 10px 15px;
|
||||
|
||||
&.add-card {
|
||||
.center {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.allowed-qualities {
|
||||
|
||||
padding-left: 0px;
|
||||
|
||||
li {
|
||||
list-style-type : none;
|
||||
margin: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.language {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ define(
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.qualityProfileCollection = options.qualityProfiles;
|
||||
this.profileCollection = options.profiles;
|
||||
this.filesize = fileSize;
|
||||
},
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'underscore',
|
||||
'marionette',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Mixins/AsValidatedView'
|
||||
], function (_, Marionette, AsModelBoundView, AsValidatedView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Settings/Quality/Profile/Edit/EditQualityProfileViewTemplate',
|
||||
|
||||
ui: {
|
||||
cutoff : '.x-cutoff'
|
||||
},
|
||||
|
||||
getCutoff: function () {
|
||||
var self = this;
|
||||
|
||||
return _.findWhere(_.pluck(this.model.get('items'), 'quality'), { id: parseInt(self.ui.cutoff.val(), 10)});
|
||||
}
|
||||
});
|
||||
|
||||
AsValidatedView.call(view);
|
||||
return AsModelBoundView.call(view);
|
||||
});
|
||||
@@ -1,23 +0,0 @@
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Name</label>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" name="name" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Cutoff</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control x-cutoff" name="cutoff.id" validation-name="cutoff">
|
||||
{{#eachReverse items}}
|
||||
{{#if allowed}}
|
||||
<option value="{{quality.id}}">{{quality.name}}</option>
|
||||
{{/if}}
|
||||
{{/eachReverse}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-nd-form-info" title="Once this quality is reached NzbDrone will no longer download episodes"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,22 +0,0 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone.collectionview',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileItemView'
|
||||
], function (BackboneSortableCollectionView, EditQualityProfileItemView) {
|
||||
return BackboneSortableCollectionView.extend({
|
||||
|
||||
className: 'qualities',
|
||||
modelView: EditQualityProfileItemView,
|
||||
|
||||
attributes: {
|
||||
'validation-name': 'items'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click li, td' : '_listItem_onMousedown',
|
||||
'dblclick li, td' : '_listItem_onDoubleClick',
|
||||
'keydown' : '_onKeydown'
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'Quality/QualityProfileModel'
|
||||
], function (Backbone, QualityProfileModel) {
|
||||
|
||||
return Backbone.Collection.extend({
|
||||
model: QualityProfileModel,
|
||||
url : window.NzbDrone.ApiRoot + '/qualityprofile/schema'
|
||||
});
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
<div class="quality-profile-item thingy" title="Click to edit">
|
||||
<div>
|
||||
<h3 name="name"></h3>
|
||||
</div>
|
||||
|
||||
<ul class="allowed-qualities">
|
||||
{{allowedLabeler}}
|
||||
</ul>
|
||||
</div>
|
||||
@@ -3,28 +3,23 @@
|
||||
define(
|
||||
[
|
||||
'marionette',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Settings/Quality/Profile/QualityProfileCollectionView',
|
||||
'Quality/QualityDefinitionCollection',
|
||||
'Settings/Quality/Definition/QualityDefinitionCollectionView'
|
||||
], function (Marionette, QualityProfileCollection, QualityProfileCollectionView, QualityDefinitionCollection, QualityDefinitionCollectionView) {
|
||||
], function (Marionette, QualityDefinitionCollection, QualityDefinitionCollectionView) {
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Settings/Quality/QualityLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
qualityProfile : '#quality-profile',
|
||||
qualityDefinition : '#quality-definition'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.settings = options.settings;
|
||||
QualityProfileCollection.fetch();
|
||||
this.qualityDefinitionCollection = new QualityDefinitionCollection();
|
||||
this.qualityDefinitionCollection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.qualityProfile.show(new QualityProfileCollectionView({collection: QualityProfileCollection}));
|
||||
this.qualityDefinition.show(new QualityDefinitionCollectionView({collection: this.qualityDefinitionCollection}));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12" id="quality-profile"/>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="row advanced-setting">
|
||||
<div class="col-md-12" id="quality-definition"/>
|
||||
</div>
|
||||
|
||||
@@ -2,30 +2,6 @@
|
||||
@import "../../Content/FontAwesome/font-awesome";
|
||||
@import "../../Shared/Styles/clickable.less";
|
||||
|
||||
.quality-profile-item {
|
||||
.clickable;
|
||||
|
||||
width: 300px;
|
||||
height: 120px;
|
||||
padding: 10px 15px;
|
||||
|
||||
&.add-card {
|
||||
.center {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.allowed-qualities {
|
||||
|
||||
padding-left: 0px;
|
||||
|
||||
li {
|
||||
list-style-type : none;
|
||||
margin: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.qualities {
|
||||
.user-select(none);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ define(
|
||||
'Settings/MediaManagement/Naming/NamingModel',
|
||||
'Settings/MediaManagement/MediaManagementLayout',
|
||||
'Settings/MediaManagement/MediaManagementSettingsModel',
|
||||
'Settings/Profile/ProfileLayout',
|
||||
'Settings/Quality/QualityLayout',
|
||||
'Settings/Indexers/IndexerLayout',
|
||||
'Settings/Indexers/IndexerCollection',
|
||||
@@ -31,6 +32,7 @@ define(
|
||||
NamingModel,
|
||||
MediaManagementLayout,
|
||||
MediaManagementSettingsModel,
|
||||
ProfileLayout,
|
||||
QualityLayout,
|
||||
IndexerLayout,
|
||||
IndexerCollection,
|
||||
@@ -48,6 +50,7 @@ define(
|
||||
|
||||
regions: {
|
||||
mediaManagement : '#media-management',
|
||||
profiles : '#profiles',
|
||||
quality : '#quality',
|
||||
indexers : '#indexers',
|
||||
downloadClient : '#download-client',
|
||||
@@ -59,6 +62,7 @@ define(
|
||||
|
||||
ui: {
|
||||
mediaManagementTab : '.x-media-management-tab',
|
||||
profilesTab : '.x-profiles-tab',
|
||||
qualityTab : '.x-quality-tab',
|
||||
indexersTab : '.x-indexers-tab',
|
||||
downloadClientTab : '.x-download-client-tab',
|
||||
@@ -70,6 +74,7 @@ define(
|
||||
|
||||
events: {
|
||||
'click .x-media-management-tab' : '_showMediaManagement',
|
||||
'click .x-profiles-tab' : '_showProfiles',
|
||||
'click .x-quality-tab' : '_showQuality',
|
||||
'click .x-indexers-tab' : '_showIndexers',
|
||||
'click .x-download-client-tab' : '_showDownloadClient',
|
||||
@@ -109,6 +114,7 @@ define(
|
||||
{
|
||||
self.loading.$el.hide();
|
||||
self.mediaManagement.show(new MediaManagementLayout({ settings: self.mediaManagementSettings, namingSettings: self.namingSettings }));
|
||||
self.profiles.show(new ProfileLayout());
|
||||
self.quality.show(new QualityLayout());
|
||||
self.indexers.show(new IndexerLayout({ model: self.indexerSettings }));
|
||||
self.downloadClient.show(new DownloadClientLayout({ model: self.downloadClientSettings }));
|
||||
@@ -123,6 +129,9 @@ define(
|
||||
|
||||
onShow: function () {
|
||||
switch (this.action) {
|
||||
case 'profiles':
|
||||
this._showProfiles();
|
||||
break;
|
||||
case 'quality':
|
||||
this._showQuality();
|
||||
break;
|
||||
@@ -158,6 +167,15 @@ define(
|
||||
this._navigate('settings/mediamanagement');
|
||||
},
|
||||
|
||||
_showProfiles: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
this.ui.profilesTab.tab('show');
|
||||
this._navigate('settings/profiles');
|
||||
},
|
||||
|
||||
_showQuality: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-tabs nav-justified settings-tabs">
|
||||
<li><a href="#media-management" class="x-media-management-tab no-router">Media Management</a></li>
|
||||
<li><a href="#profiles" class="x-profiles-tab no-router">Profiles</a></li>
|
||||
<li><a href="#quality" class="x-quality-tab no-router">Quality</a></li>
|
||||
<li><a href="#indexers" class="x-indexers-tab no-router">Indexers</a></li>
|
||||
<li><a href="#download-client" class="x-download-client-tab no-router">Download Client</a></li>
|
||||
@@ -34,6 +35,7 @@
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" id="media-management"></div>
|
||||
<div class="tab-pane" id="profiles"></div>
|
||||
<div class="tab-pane" id="quality"></div>
|
||||
<div class="tab-pane" id="indexers"></div>
|
||||
<div class="tab-pane" id="download-client"></div>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@import "../Shared/Styles/clickable.less";
|
||||
@import "Indexers/indexers";
|
||||
@import "Quality/quality";
|
||||
@import "Profile/profile";
|
||||
@import "Notifications/notifications";
|
||||
@import "Metadata/metadata";
|
||||
@import "DownloadClient/downloadclient";
|
||||
|
||||
Reference in New Issue
Block a user