UI Cleanup - Updated Settings subtree.

This commit is contained in:
Taloth Saldono
2015-02-14 00:37:11 +01:00
parent b69ea349ce
commit 019525dd9d
72 changed files with 1458 additions and 1039 deletions

View File

@@ -1,20 +1,19 @@
var Handlebars = require('handlebars');
var _ = require('underscore');
module.exports = (function(){
Handlebars.registerHelper('allowedLabeler', function(){
var ret = '';
var cutoff = this.cutoff;
_.each(this.items, function(item){
if(item.allowed) {
if(item.quality.id === cutoff.id) {
ret += '<li><span class="label label-info" title="Cutoff">' + item.quality.name + '</span></li>';
}
else {
ret += '<li><span class="label label-default">' + item.quality.name + '</span></li>';
}
Handlebars.registerHelper('allowedLabeler', function() {
var ret = '';
var cutoff = this.cutoff;
_.each(this.items, function(item) {
if (item.allowed) {
if (item.quality.id === cutoff.id) {
ret += '<li><span class="label label-info" title="Cutoff">' + item.quality.name + '</span></li>';
} else {
ret += '<li><span class="label label-default">' + item.quality.name + '</span></li>';
}
});
return new Handlebars.SafeString(ret);
}
});
}).call(this);
return new Handlebars.SafeString(ret);
});

View File

@@ -4,9 +4,10 @@ var DelayProfileItemView = require('./DelayProfileItemView');
module.exports = BackboneSortableCollectionView.extend({
className : 'delay-profiles',
modelView : DelayProfileItemView,
events : {
"click li, td" : '_listItem_onMousedown',
"dblclick li, td" : '_listItem_onDoubleClick',
"keydown" : '_onKeydown'
events : {
'click li, td' : '_listItem_onMousedown',
'dblclick li, td' : '_listItem_onDoubleClick',
'keydown' : '_onKeydown'
}
});

View File

@@ -4,13 +4,18 @@ var Marionette = require('marionette');
var EditView = require('./Edit/DelayProfileEditView');
module.exports = Marionette.ItemView.extend({
template : 'Settings/Profile/Delay/DelayProfileItemViewTemplate',
className : 'row',
events : {"click .x-edit" : '_edit'},
initialize : function(){
template : 'Settings/Profile/Delay/DelayProfileItemViewTemplate',
className : 'row',
events : {
'click .x-edit' : '_edit'
},
initialize : function() {
this.listenTo(this.model, 'sync', this.render);
},
_edit : function(){
_edit : function() {
var view = new EditView({
model : this.model,
targetCollection : this.model.collection

View File

@@ -1,4 +1,4 @@
var $ = require('jquery');
var $ = require('jquery');
var _ = require('underscore');
var vent = require('vent');
var AppLayout = require('../../../AppLayout');
@@ -9,45 +9,67 @@ var EditView = require('./Edit/DelayProfileEditView');
var Model = require('./DelayProfileModel');
module.exports = Marionette.Layout.extend({
template : 'Settings/Profile/Delay/DelayProfileLayoutTemplate',
regions : {delayProfiles : '.x-rows'},
events : {"click .x-add" : '_add'},
initialize : function(options){
template : 'Settings/Profile/Delay/DelayProfileLayoutTemplate',
regions : {
delayProfiles : '.x-rows'
},
events : {
'click .x-add' : '_add'
},
initialize : function(options) {
this.collection = options.collection;
this._updateOrderedCollection();
this.listenTo(this.collection, 'sync', this._updateOrderedCollection);
this.listenTo(this.collection, 'add', this._updateOrderedCollection);
this.listenTo(this.collection, 'remove', function(){
this.listenTo(this.collection, 'remove', function() {
this.collection.fetch();
});
},
onRender : function(){
onRender : function() {
this.sortableListView = new DelayProfileCollectionView({
sortable : true,
collection : this.orderedCollection,
sortableOptions : {handle : '.x-drag-handle'},
sortableModelsFilter : function(model){
sortable : true,
collection : this.orderedCollection,
sortableOptions : {
handle : '.x-drag-handle'
},
sortableModelsFilter : function(model) {
return model.get('id') !== 1;
}
});
this.delayProfiles.show(this.sortableListView);
this.listenTo(this.sortableListView, 'sortStop', this._updateOrder);
},
_updateOrder : function(){
_updateOrder : function() {
var self = this;
this.collection.forEach(function(model){
if(model.get('id') === 1) {
this.collection.forEach(function(model) {
if (model.get('id') === 1) {
return;
}
var orderedModel = self.orderedCollection.get(model);
var order = self.orderedCollection.indexOf(orderedModel) + 1;
if(model.get('order') !== order) {
if (model.get('order') !== order) {
model.set('order', order);
model.save();
}
});
},
_add : function(){
_add : function() {
var model = new Model({
enableUsenet : true,
enableTorrent : true,
@@ -57,18 +79,22 @@ module.exports = Marionette.Layout.extend({
order : this.collection.length,
tags : []
});
model.collection = this.collection;
var view = new EditView({
model : model,
targetCollection : this.collection
});
AppLayout.modalRegion.show(view);
},
_updateOrderedCollection : function(){
if(!this.orderedCollection) {
_updateOrderedCollection : function() {
if (!this.orderedCollection) {
this.orderedCollection = new Backbone.Collection();
}
this.orderedCollection.reset(_.sortBy(this.collection.models, function(model){
this.orderedCollection.reset(_.sortBy(this.collection.models, function(model) {
return model.get('order');
}));
}

View File

@@ -3,12 +3,17 @@ var Marionette = require('marionette');
module.exports = Marionette.ItemView.extend({
template : 'Settings/Profile/Delay/Delete/DelayProfileDeleteViewTemplate',
events : {"click .x-confirm-delete" : '_delete'},
_delete : function(){
events : {
'click .x-confirm-delete' : '_delete'
},
_delete : function() {
var collection = this.model.collection;
this.model.destroy({
wait : true,
success : function(){
success : function() {
vent.trigger(vent.Commands.CloseModalCommand);
}
});

View File

@@ -1,4 +1,4 @@
var vent = require('vent');
var vent = require('vent');
var AppLayout = require('../../../../AppLayout');
var Marionette = require('marionette');
var DeleteView = require('../Delete/DelayProfileDeleteView');
@@ -8,93 +8,115 @@ var AsEditModalView = require('../../../../Mixins/AsEditModalView');
require('../../../../Mixins/TagInput');
require('bootstrap');
module.exports = (function(){
var view = Marionette.ItemView.extend({
template : 'Settings/Profile/Delay/Edit/DelayProfileEditViewTemplate',
_deleteView : DeleteView,
ui : {
tags : '.x-tags',
usenetDelay : '.x-usenet-delay',
torrentDelay : '.x-torrent-delay',
protocol : '.x-protocol'
},
events : {"change .x-protocol" : '_updateModel'},
initialize : function(options){
this.targetCollection = options.targetCollection;
},
onRender : function(){
if(this.model.id !== 1) {
this.ui.tags.tagInput({
model : this.model,
property : 'tags'
});
}
this._toggleControls();
},
_onAfterSave : function(){
this.targetCollection.add(this.model, {merge : true});
vent.trigger(vent.Commands.CloseModalCommand);
},
_updateModel : function(){
var protocol = this.ui.protocol.val();
if(protocol === 'preferUsenet') {
this.model.set({
enableUsenet : true,
enableTorrent : true,
preferredProtocol : 'usenet'
});
}
if(protocol === 'preferTorrent') {
this.model.set({
enableUsenet : true,
enableTorrent : true,
preferredProtocol : 'torrent'
});
}
if(protocol === 'onlyUsenet') {
this.model.set({
enableUsenet : true,
enableTorrent : false,
preferredProtocol : 'usenet'
});
}
if(protocol === 'onlyTorrent') {
this.model.set({
enableUsenet : false,
enableTorrent : true,
preferredProtocol : 'torrent'
});
}
this._toggleControls();
},
_toggleControls : function(){
var enableUsenet = this.model.get('enableUsenet');
var enableTorrent = this.model.get('enableTorrent');
var preferred = this.model.get('preferredProtocol');
if(preferred === 'usenet') {
this.ui.protocol.val('preferUsenet');
}
else {
this.ui.protocol.val('preferTorrent');
}
if(enableUsenet) {
this.ui.usenetDelay.show();
}
else {
this.ui.protocol.val('onlyTorrent');
this.ui.usenetDelay.hide();
}
if(enableTorrent) {
this.ui.torrentDelay.show();
}
else {
this.ui.protocol.val('onlyUsenet');
this.ui.torrentDelay.hide();
}
var view = Marionette.ItemView.extend({
template : 'Settings/Profile/Delay/Edit/DelayProfileEditViewTemplate',
_deleteView : DeleteView,
ui : {
tags : '.x-tags',
usenetDelay : '.x-usenet-delay',
torrentDelay : '.x-torrent-delay',
protocol : '.x-protocol'
},
events : {
'change .x-protocol' : '_updateModel'
},
initialize : function(options) {
this.targetCollection = options.targetCollection;
},
onRender : function() {
if (this.model.id !== 1) {
this.ui.tags.tagInput({
model : this.model,
property : 'tags'
});
}
});
AsModelBoundView.call(view);
AsValidatedView.call(view);
AsEditModalView.call(view);
return view;
}).call(this);
this._toggleControls();
},
_onAfterSave : function() {
this.targetCollection.add(this.model, { merge : true });
vent.trigger(vent.Commands.CloseModalCommand);
},
_updateModel : function() {
var protocol = this.ui.protocol.val();
if (protocol === 'preferUsenet') {
this.model.set({
enableUsenet : true,
enableTorrent : true,
preferredProtocol : 'usenet'
});
}
if (protocol === 'preferTorrent') {
this.model.set({
enableUsenet : true,
enableTorrent : true,
preferredProtocol : 'torrent'
});
}
if (protocol === 'onlyUsenet') {
this.model.set({
enableUsenet : true,
enableTorrent : false,
preferredProtocol : 'usenet'
});
}
if (protocol === 'onlyTorrent') {
this.model.set({
enableUsenet : false,
enableTorrent : true,
preferredProtocol : 'torrent'
});
}
this._toggleControls();
},
_toggleControls : function() {
var enableUsenet = this.model.get('enableUsenet');
var enableTorrent = this.model.get('enableTorrent');
var preferred = this.model.get('preferredProtocol');
if (preferred === 'usenet') {
this.ui.protocol.val('preferUsenet');
}
else {
this.ui.protocol.val('preferTorrent');
}
if (enableUsenet) {
this.ui.usenetDelay.show();
}
else {
this.ui.protocol.val('onlyTorrent');
this.ui.usenetDelay.hide();
}
if (enableTorrent) {
this.ui.torrentDelay.show();
}
else {
this.ui.protocol.val('onlyUsenet');
this.ui.torrentDelay.hide();
}
}
});
AsModelBoundView.call(view);
AsValidatedView.call(view);
AsEditModalView.call(view);
module.exports = view;

View File

@@ -2,10 +2,14 @@ var vent = require('vent');
var Marionette = require('marionette');
module.exports = Marionette.ItemView.extend({
template : 'Settings/Profile/DeleteProfileViewTemplate',
events : {"click .x-confirm-delete" : '_removeProfile'},
_removeProfile : function(){
this.model.destroy({wait : true}).done(function(){
template : 'Settings/Profile/DeleteProfileViewTemplate',
events : {
'click .x-confirm-delete' : '_removeProfile'
},
_removeProfile : function() {
this.model.destroy({ wait : true }).done(function() {
vent.trigger(vent.Commands.CloseModalCommand);
});
}

View File

@@ -1,3 +1,5 @@
var Marionette = require('marionette');
module.exports = Marionette.ItemView.extend({template : 'Settings/Profile/Edit/EditProfileItemViewTemplate'});
module.exports = Marionette.ItemView.extend({
template : 'Settings/Profile/Edit/EditProfileItemViewTemplate'
});

View File

@@ -1,4 +1,4 @@
var _ = require('underscore');
var _ = require('underscore');
var vent = require('vent');
var AppLayout = require('../../../AppLayout');
var Marionette = require('marionette');
@@ -11,85 +11,107 @@ var SeriesCollection = require('../../../Series/SeriesCollection');
var Config = require('../../../Config');
var AsEditModalView = require('../../../Mixins/AsEditModalView');
module.exports = (function(){
var view = Marionette.Layout.extend({
template : 'Settings/Profile/Edit/EditProfileLayoutTemplate',
regions : {
fields : '#x-fields',
qualities : '#x-qualities'
},
ui : {deleteButton : '.x-delete'},
_deleteView : DeleteView,
initialize : function(options){
this.profileCollection = options.profileCollection;
this.itemsCollection = new Backbone.Collection(_.toArray(this.model.get('items')).reverse());
this.listenTo(SeriesCollection, 'all', this._updateDisableStatus);
},
onRender : function(){
this._updateDisableStatus();
},
onShow : function(){
this.fieldsView = new EditProfileView({model : this.model});
this._showFieldsView();
var advancedShown = Config.getValueBoolean(Config.Keys.AdvancedSettings, false);
this.sortableListView = new QualitySortableCollectionView({
selectable : true,
selectMultiple : true,
clickToSelect : true,
clickToToggle : true,
sortable : advancedShown,
sortableOptions : {handle : '.x-drag-handle'},
visibleModelsFilter : function(model){
return model.get('quality').id !== 0 || advancedShown;
},
collection : this.itemsCollection,
model : this.model
});
this.sortableListView.setSelectedModels(this.itemsCollection.filter(function(item){
return item.get('allowed') === true;
}));
this.qualities.show(this.sortableListView);
this.listenTo(this.sortableListView, 'selectionChanged', this._selectionChanged);
this.listenTo(this.sortableListView, 'sortStop', this._updateModel);
},
_onBeforeSave : function(){
var cutoff = this.fieldsView.getCutoff();
this.model.set('cutoff', cutoff);
},
_onAfterSave : function(){
this.profileCollection.add(this.model, {merge : true});
vent.trigger(vent.Commands.CloseModalCommand);
},
_selectionChanged : function(newSelectedModels, oldSelectedModels){
var addedModels = _.difference(newSelectedModels, oldSelectedModels);
var removeModels = _.difference(oldSelectedModels, newSelectedModels);
_.each(removeModels, function(item){
item.set('allowed', false);
});
_.each(addedModels, function(item){
item.set('allowed', true);
});
this._updateModel();
},
_updateModel : function(){
this.model.set('items', this.itemsCollection.toJSON().reverse());
this._showFieldsView();
},
_showFieldsView : function(){
this.fields.show(this.fieldsView);
},
_updateDisableStatus : function(){
if(this._isQualityInUse()) {
this.ui.deleteButton.addClass('disabled');
this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a series.');
}
else {
this.ui.deleteButton.removeClass('disabled');
}
},
_isQualityInUse : function(){
return SeriesCollection.where({"profileId" : this.model.id}).length !== 0;
var view = Marionette.Layout.extend({
template : 'Settings/Profile/Edit/EditProfileLayoutTemplate',
regions : {
fields : '#x-fields',
qualities : '#x-qualities'
},
ui : {
deleteButton : '.x-delete'
},
_deleteView : DeleteView,
initialize : function(options) {
this.profileCollection = options.profileCollection;
this.itemsCollection = new Backbone.Collection(_.toArray(this.model.get('items')).reverse());
this.listenTo(SeriesCollection, 'all', this._updateDisableStatus);
},
onRender : function() {
this._updateDisableStatus();
},
onShow : function() {
this.fieldsView = new EditProfileView({ model : this.model });
this._showFieldsView();
var advancedShown = Config.getValueBoolean(Config.Keys.AdvancedSettings, false);
this.sortableListView = new QualitySortableCollectionView({
selectable : true,
selectMultiple : true,
clickToSelect : true,
clickToToggle : true,
sortable : advancedShown,
sortableOptions : {
handle : '.x-drag-handle'
},
visibleModelsFilter : function(model) {
return model.get('quality').id !== 0 || advancedShown;
},
collection : this.itemsCollection,
model : this.model
});
this.sortableListView.setSelectedModels(this.itemsCollection.filter(function(item) {
return item.get('allowed') === true;
}));
this.qualities.show(this.sortableListView);
this.listenTo(this.sortableListView, 'selectionChanged', this._selectionChanged);
this.listenTo(this.sortableListView, 'sortStop', this._updateModel);
},
_onBeforeSave : function() {
var cutoff = this.fieldsView.getCutoff();
this.model.set('cutoff', cutoff);
},
_onAfterSave : function() {
this.profileCollection.add(this.model, { merge : true });
vent.trigger(vent.Commands.CloseModalCommand);
},
_selectionChanged : function(newSelectedModels, oldSelectedModels) {
var addedModels = _.difference(newSelectedModels, oldSelectedModels);
var removeModels = _.difference(oldSelectedModels, newSelectedModels);
_.each(removeModels, function(item) {
item.set('allowed', false);
});
_.each(addedModels, function(item) {
item.set('allowed', true);
});
this._updateModel();
},
_updateModel : function() {
this.model.set('items', this.itemsCollection.toJSON().reverse());
this._showFieldsView();
},
_showFieldsView : function() {
this.fields.show(this.fieldsView);
},
_updateDisableStatus : function() {
if (this._isQualityInUse()) {
this.ui.deleteButton.addClass('disabled');
this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a series.');
} else {
this.ui.deleteButton.removeClass('disabled');
}
});
return AsEditModalView.call(view);
}).call(this);
},
_isQualityInUse : function() {
return SeriesCollection.where({ 'profileId' : this.model.id }).length !== 0;
}
});
module.exports = AsEditModalView.call(view);

View File

@@ -5,18 +5,24 @@ var Config = require('../../../Config');
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
var AsValidatedView = require('../../../Mixins/AsValidatedView');
module.exports = (function(){
var view = Marionette.ItemView.extend({
template : 'Settings/Profile/Edit/EditProfileViewTemplate',
ui : {cutoff : '.x-cutoff'},
templateHelpers : function(){
return {languages : LanguageCollection.toJSON()};
},
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);
}).call(this);
var view = Marionette.ItemView.extend({
template : 'Settings/Profile/Edit/EditProfileViewTemplate',
ui : { cutoff : '.x-cutoff' },
templateHelpers : function() {
return {
languages : LanguageCollection.toJSON()
};
},
getCutoff : function() {
var self = this;
return _.findWhere(_.pluck(this.model.get('items'), 'quality'), { id : parseInt(self.ui.cutoff.val(), 10) });
}
});
AsValidatedView.call(view);
module.exports = AsModelBoundView.call(view);

View File

@@ -2,12 +2,16 @@ var BackboneSortableCollectionView = require('backbone.collectionview');
var EditProfileItemView = require('./EditProfileItemView');
module.exports = BackboneSortableCollectionView.extend({
className : 'qualities',
modelView : EditProfileItemView,
attributes : {"validation-name" : 'items'},
events : {
"click li, td" : '_listItem_onMousedown',
"dblclick li, td" : '_listItem_onDoubleClick',
"keydown" : '_onKeydown'
className : 'qualities',
modelView : EditProfileItemView,
attributes : {
'validation-name' : 'items'
},
events : {
'click li, td' : '_listItem_onMousedown',
'dblclick li, td' : '_listItem_onDoubleClick',
'keydown' : '_onKeydown'
}
});

View File

@@ -1,12 +1,12 @@
var Backbone = require('backbone');
var LanguageModel = require('./LanguageModel');
module.exports = (function(){
var LanuageCollection = Backbone.Collection.extend({
model : LanguageModel,
url : window.NzbDrone.ApiRoot + '/language'
});
var languages = new LanuageCollection();
languages.fetch();
return languages;
}).call(this);
var LanuageCollection = Backbone.Collection.extend({
model : LanguageModel,
url : window.NzbDrone.ApiRoot + '/language'
});
var languages = new LanuageCollection();
languages.fetch();
module.exports = languages;

View File

@@ -2,13 +2,14 @@ var _ = require('underscore');
var Handlebars = require('handlebars');
var LanguageCollection = require('./Language/LanguageCollection');
module.exports = (function(){
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);
Handlebars.registerHelper('languageLabel', function() {
var wantedLanguage = this.language;
var language = LanguageCollection.find(function(lang) {
return lang.get('nameLower') === wantedLanguage;
});
}).call(this);
var result = '<span class="label label-primary">' + language.get('name') + '</span>';
return new Handlebars.SafeString(result);
});

View File

@@ -9,16 +9,24 @@ module.exports = Marionette.CompositeView.extend({
itemView : ProfileView,
itemViewContainer : '.profiles',
template : 'Settings/Profile/ProfileCollectionTemplate',
ui : {"addCard" : '.x-add-card'},
events : {"click .x-add-card" : '_addProfile'},
appendHtml : function(collectionView, itemView, index){
ui : {
'addCard' : '.x-add-card'
},
events : {
'click .x-add-card' : '_addProfile'
},
appendHtml : function(collectionView, itemView, index) {
collectionView.ui.addCard.parent('li').before(itemView.el);
},
_addProfile : function(){
_addProfile : function() {
var self = this;
var schemaCollection = new ProfileCollection();
schemaCollection.fetch({
success : function(collection){
success : function(collection) {
var model = _.first(collection.models);
model.set('id', undefined);
model.set('name', '');
@@ -27,6 +35,7 @@ module.exports = Marionette.CompositeView.extend({
model : model,
profileCollection : self.collection
});
AppLayout.modalRegion.show(view);
}
});

View File

@@ -6,19 +6,23 @@ var DelayProfileCollection = require('./Delay/DelayProfileCollection');
var LanguageCollection = require('./Language/LanguageCollection');
module.exports = Marionette.Layout.extend({
template : 'Settings/Profile/ProfileLayoutTemplate',
regions : {
template : 'Settings/Profile/ProfileLayoutTemplate',
regions : {
profile : '#profile',
delayProfile : '#delay-profile'
},
initialize : function(options){
initialize : function(options) {
this.settings = options.settings;
ProfileCollection.fetch();
this.delayProfileCollection = new DelayProfileCollection();
this.delayProfileCollection.fetch();
},
onShow : function(){
this.profile.show(new ProfileCollectionView({collection : ProfileCollection}));
this.delayProfile.show(new DelayProfileLayout({collection : this.delayProfileCollection}));
onShow : function() {
this.profile.show(new ProfileCollectionView({ collection : ProfileCollection }));
this.delayProfile.show(new DelayProfileLayout({ collection : this.delayProfileCollection }));
}
});

View File

@@ -6,25 +6,30 @@ require('./AllowedLabeler');
require('./LanguageLabel');
require('bootstrap');
module.exports = (function(){
var view = Marionette.ItemView.extend({
template : 'Settings/Profile/ProfileViewTemplate',
tagName : 'li',
ui : {
"progressbar" : '.progress .bar',
"deleteButton" : '.x-delete'
},
events : {"click" : '_editProfile'},
initialize : function(){
this.listenTo(this.model, 'sync', this.render);
},
_editProfile : function(){
var view = new EditProfileView({
model : this.model,
profileCollection : this.model.collection
});
AppLayout.modalRegion.show(view);
}
});
return AsModelBoundView.call(view);
}).call(this);
var view = Marionette.ItemView.extend({
template : 'Settings/Profile/ProfileViewTemplate',
tagName : 'li',
ui : {
"progressbar" : '.progress .bar',
"deleteButton" : '.x-delete'
},
events : {
'click' : '_editProfile'
},
initialize : function() {
this.listenTo(this.model, 'sync', this.render);
},
_editProfile : function() {
var view = new EditProfileView({
model : this.model,
profileCollection : this.model.collection
});
AppLayout.modalRegion.show(view);
}
});
module.exports = AsModelBoundView.call(view);