parent
2c52795822
commit
463d85e479
@ -0,0 +1,9 @@
|
||||
var ThingyAddCollectionView = require('../../ThingyAddCollectionView');
|
||||
var ThingyHeaderGroupView = require('../../ThingyHeaderGroupView');
|
||||
var AddItemView = require('./IndexerAddItemView');
|
||||
|
||||
module.exports = ThingyAddCollectionView.extend({
|
||||
itemView : ThingyHeaderGroupView.extend({ itemView : AddItemView }),
|
||||
itemViewContainer : '.add-indexer .items',
|
||||
template : 'Settings/Indexers/Add/IndexerAddCollectionViewTemplate'
|
||||
});
|
@ -0,0 +1,18 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Add Indexer</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-info">
|
||||
Radarr supports any indexer that uses the Newznab standard, as well as other indexers listed below.<br/>
|
||||
For more information on the individual indexers, click on the info buttons.
|
||||
</div>
|
||||
<div class="add-indexer add-thingies">
|
||||
<ul class="items"></ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,52 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var AppLayout = require('../../../AppLayout');
|
||||
var Marionette = require('marionette');
|
||||
var EditView = require('../Edit/IndexerEditView');
|
||||
|
||||
module.exports = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Add/IndexerAddItemViewTemplate',
|
||||
tagName : 'li',
|
||||
className : 'add-thingy-item',
|
||||
|
||||
events : {
|
||||
'click .x-preset' : '_addPreset',
|
||||
'click' : '_add'
|
||||
},
|
||||
|
||||
initialize : function(options) {
|
||||
this.targetCollection = options.targetCollection;
|
||||
},
|
||||
|
||||
_addPreset : function(e) {
|
||||
var presetName = $(e.target).closest('.x-preset').attr('data-id');
|
||||
var presetData = _.where(this.model.get('presets'), { name : presetName })[0];
|
||||
|
||||
this.model.set(presetData);
|
||||
|
||||
this._openEdit();
|
||||
},
|
||||
|
||||
_add : function(e) {
|
||||
if ($(e.target).closest('.btn,.btn-group').length !== 0 && $(e.target).closest('.x-custom').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._openEdit();
|
||||
},
|
||||
|
||||
_openEdit : function() {
|
||||
this.model.set({
|
||||
id : undefined,
|
||||
enableRss : this.model.get('supportsRss'),
|
||||
enableSearch : this.model.get('supportsSearch')
|
||||
});
|
||||
|
||||
var editView = new EditView({
|
||||
model : this.model,
|
||||
targetCollection : this.targetCollection
|
||||
});
|
||||
|
||||
AppLayout.modalRegion.show(editView);
|
||||
}
|
||||
});
|
@ -0,0 +1,30 @@
|
||||
<div class="add-thingy">
|
||||
<div>
|
||||
{{implementationName}}
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
{{#if_gt presets.length compare=0}}
|
||||
<button class="btn btn-xs btn-default x-custom">
|
||||
Custom
|
||||
</button>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Presets
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{{#each presets}}
|
||||
<li class="x-preset" data-id="{{name}}">
|
||||
<a>{{name}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if_gt}}
|
||||
{{#if infoLink}}
|
||||
<a class="btn btn-xs btn-default x-info" href="{{infoLink}}">
|
||||
<i class="icon-sonarr-form-info"/>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,39 @@
|
||||
var _ = require('underscore');
|
||||
var AppLayout = require('../../../AppLayout');
|
||||
var Backbone = require('backbone');
|
||||
var SchemaCollection = require('../IndexerCollection');
|
||||
var AddCollectionView = require('./IndexerAddCollectionView');
|
||||
|
||||
module.exports = {
|
||||
open : function(collection) {
|
||||
var schemaCollection = new SchemaCollection();
|
||||
var originalUrl = schemaCollection.url;
|
||||
schemaCollection.url = schemaCollection.url + '/schema';
|
||||
schemaCollection.fetch();
|
||||
schemaCollection.url = originalUrl;
|
||||
|
||||
var groupedSchemaCollection = new Backbone.Collection();
|
||||
|
||||
schemaCollection.on('sync', function() {
|
||||
|
||||
var groups = schemaCollection.groupBy(function(model, iterator) {
|
||||
return model.get('protocol');
|
||||
});
|
||||
var modelCollection = _.map(groups, function(values, key, list) {
|
||||
return {
|
||||
"header" : key,
|
||||
collection : values
|
||||
};
|
||||
});
|
||||
|
||||
groupedSchemaCollection.reset(modelCollection);
|
||||
});
|
||||
|
||||
var view = new AddCollectionView({
|
||||
collection : groupedSchemaCollection,
|
||||
targetCollection : collection
|
||||
});
|
||||
|
||||
AppLayout.modalRegion.show(view);
|
||||
}
|
||||
};
|
@ -0,0 +1,19 @@
|
||||
var vent = require('vent');
|
||||
var Marionette = require('marionette');
|
||||
|
||||
module.exports = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Delete/IndexerDeleteViewTemplate',
|
||||
|
||||
events : {
|
||||
'click .x-confirm-delete' : '_delete'
|
||||
},
|
||||
|
||||
_delete : function() {
|
||||
this.model.destroy({
|
||||
wait : true,
|
||||
success : function() {
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Delete Indexer</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Are you sure you want to delete '{{name}}'?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">Cancel</button>
|
||||
<button class="btn btn-danger x-confirm-delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,122 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var vent = require('vent');
|
||||
var Marionette = require('marionette');
|
||||
var DeleteView = require('../Delete/IndexerDeleteView');
|
||||
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||
var AsEditModalView = require('../../../Mixins/AsEditModalView');
|
||||
require('../../../Form/FormBuilder');
|
||||
require('../../../Mixins/AutoComplete');
|
||||
require('bootstrap');
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Edit/IndexerEditViewTemplate',
|
||||
|
||||
events : {
|
||||
'click .x-back' : '_back',
|
||||
'click .x-captcha-refresh' : '_onRefreshCaptcha'
|
||||
},
|
||||
|
||||
_deleteView : DeleteView,
|
||||
|
||||
initialize : function(options) {
|
||||
this.targetCollection = options.targetCollection;
|
||||
},
|
||||
|
||||
_onAfterSave : function() {
|
||||
this.targetCollection.add(this.model, { merge : true });
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
},
|
||||
|
||||
_onAfterSaveAndAdd : function() {
|
||||
this.targetCollection.add(this.model, { merge : true });
|
||||
|
||||
require('../Add/IndexerSchemaModal').open(this.targetCollection);
|
||||
},
|
||||
|
||||
_back : function() {
|
||||
if (this.model.isNew()) {
|
||||
this.model.destroy();
|
||||
}
|
||||
|
||||
require('../Add/IndexerSchemaModal').open(this.targetCollection);
|
||||
},
|
||||
|
||||
_onRefreshCaptcha : function(event) {
|
||||
var self = this;
|
||||
|
||||
var target = $(event.target).parents('.input-group');
|
||||
|
||||
this.ui.indicator.show();
|
||||
|
||||
this.model.requestAction("checkCaptcha")
|
||||
.then(function(result) {
|
||||
if (!result.captchaRequest) {
|
||||
self.model.setFieldValue('CaptchaToken', '');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return self._showCaptcha(target, result.captchaRequest);
|
||||
})
|
||||
.always(function() {
|
||||
self.ui.indicator.hide();
|
||||
});
|
||||
},
|
||||
|
||||
_showCaptcha : function(target, captchaRequest) {
|
||||
var self = this;
|
||||
|
||||
var widget = $('<div class="g-recaptcha"></div>').insertAfter(target);
|
||||
|
||||
return this._loadRecaptchaWidget(widget[0], captchaRequest.siteKey, captchaRequest.secretToken)
|
||||
.then(function(captchaResponse) {
|
||||
target.parents('.form-group').removeAllErrors();
|
||||
widget.remove();
|
||||
|
||||
var queryParams = {
|
||||
responseUrl : captchaRequest.responseUrl,
|
||||
ray : captchaRequest.ray,
|
||||
captchaResponse: captchaResponse
|
||||
};
|
||||
|
||||
return self.model.requestAction("getCaptchaCookie", queryParams);
|
||||
})
|
||||
.then(function(response) {
|
||||
self.model.setFieldValue('CaptchaToken', response.captchaToken);
|
||||
});
|
||||
},
|
||||
|
||||
_loadRecaptchaWidget : function(widget, sitekey, stoken) {
|
||||
var promise = $.Deferred();
|
||||
|
||||
var renderWidget = function() {
|
||||
window.grecaptcha.render(widget, {
|
||||
'sitekey' : sitekey,
|
||||
'stoken' : stoken,
|
||||
'callback' : promise.resolve
|
||||
});
|
||||
};
|
||||
|
||||
if (window.grecaptcha) {
|
||||
renderWidget();
|
||||
} else {
|
||||
window.grecaptchaLoadCallback = function() {
|
||||
delete window.grecaptchaLoadCallback;
|
||||
renderWidget();
|
||||
};
|
||||
|
||||
$.getScript('https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadCallback&render=explicit')
|
||||
.fail(function() { promise.reject(); });
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
|
||||
AsModelBoundView.call(view);
|
||||
AsValidatedView.call(view);
|
||||
AsEditModalView.call(view);
|
||||
|
||||
module.exports = view;
|
@ -0,0 +1,92 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-hidden="true" data-dismiss="modal">×</button>
|
||||
{{#if id}}
|
||||
<h3>Edit - {{implementationName}}</h3>
|
||||
{{else}}
|
||||
<h3>Add - {{implementationName}}</h3>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="modal-body indexer-modal">
|
||||
<div class="form-horizontal">
|
||||
<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">Enable RSS Sync</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<div class="input-group">
|
||||
<label class="checkbox toggle well">
|
||||
<input type="checkbox" name="enableRss" {{#unless supportsRss}}disabled="disabled"{{/unless}}/>
|
||||
<p>
|
||||
<span>Yes</span>
|
||||
<span>No</span>
|
||||
</p>
|
||||
|
||||
<div class="btn btn-primary slide-button"/>
|
||||
</label>
|
||||
{{#unless supportsRss}}
|
||||
<span class="help-inline-checkbox">
|
||||
<i class="icon-sonarr-form-warning" title="" data-original-title="RSS is not supported with this indexer"></i>
|
||||
</span>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Enable Search</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<div class="input-group">
|
||||
<label class="checkbox toggle well">
|
||||
|
||||
<input type="checkbox" name="enableSearch" {{#unless supportsSearch}}disabled="disabled"{{/unless}}/>
|
||||
<p>
|
||||
<span>Yes</span>
|
||||
<span>No</span>
|
||||
</p>
|
||||
|
||||
<div class="btn btn-primary slide-button"/>
|
||||
</label>
|
||||
{{#unless supportsSearch}}
|
||||
<span class="help-inline-checkbox">
|
||||
<i class="icon-sonarr-form-warning" title="" data-original-title="Search is not supported with this indexer"></i>
|
||||
</span>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{formBuilder}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{#if id}}
|
||||
<button class="btn btn-danger pull-left x-delete">Delete</button>
|
||||
{{else}}
|
||||
<button class="btn pull-left x-back">Back</button>
|
||||
{{/if}}
|
||||
<span class="indicator x-indicator"><i class="icon-sonarr-spinner fa-spin"></i></span>
|
||||
<button class="btn x-test">test <i class="x-test-icon icon-sonarr-test"/></button>
|
||||
<button class="btn" data-dismiss="modal">Cancel</button>
|
||||
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary x-save">Save</button>
|
||||
<button class="btn btn-icon-only btn-primary dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="save-and-add x-save-and-add">
|
||||
save and add
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
var Marionette = require('marionette');
|
||||
var ItemView = require('./IndexerItemView');
|
||||
var SchemaModal = require('./Add/IndexerSchemaModal');
|
||||
|
||||
module.exports = Marionette.CompositeView.extend({
|
||||
itemView : ItemView,
|
||||
itemViewContainer : '.indexer-list',
|
||||
template : 'Settings/Indexers/IndexerCollectionViewTemplate',
|
||||
|
||||
ui : {
|
||||
'addCard' : '.x-add-card'
|
||||
},
|
||||
|
||||
events : {
|
||||
'click .x-add-card' : '_openSchemaModal'
|
||||
},
|
||||
|
||||
appendHtml : function(collectionView, itemView, index) {
|
||||
collectionView.ui.addCard.parent('li').before(itemView.el);
|
||||
},
|
||||
|
||||
_openSchemaModal : function() {
|
||||
SchemaModal.open(this.collection);
|
||||
}
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
<fieldset>
|
||||
<legend>Indexers</legend>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<ul class="indexer-list thingies">
|
||||
<li>
|
||||
<div class="indexer-item thingy add-card x-add-card">
|
||||
<span class="center well">
|
||||
<i class="icon-sonarr-add"/>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
@ -0,0 +1,24 @@
|
||||
var AppLayout = require('../../AppLayout');
|
||||
var Marionette = require('marionette');
|
||||
var EditView = require('./Edit/IndexerEditView');
|
||||
|
||||
module.exports = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/IndexerItemViewTemplate',
|
||||
tagName : 'li',
|
||||
|
||||
events : {
|
||||
'click' : '_edit'
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
this.listenTo(this.model, 'sync', this.render);
|
||||
},
|
||||
|
||||
_edit : function() {
|
||||
var view = new EditView({
|
||||
model : this.model,
|
||||
targetCollection : this.model.collection
|
||||
});
|
||||
AppLayout.modalRegion.show(view);
|
||||
}
|
||||
});
|
@ -0,0 +1,27 @@
|
||||
<div class="indexer-item thingy">
|
||||
<div>
|
||||
<h3>{{name}}</h3>
|
||||
</div>
|
||||
|
||||
<div class="settings">
|
||||
{{#if supportsRss}}
|
||||
{{#if enableRss}}
|
||||
<span class="label label-success">RSS</span>
|
||||
{{else}}
|
||||
<span class="label label-default">RSS</span>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<span class="label label-default label-disabled">RSS</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if supportsSearch}}
|
||||
{{#if enableSearch}}
|
||||
<span class="label label-success">Search</span>
|
||||
{{else}}
|
||||
<span class="label label-default">Search</span>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<span class="label label-default label-disabled">Search</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,30 @@
|
||||
var Marionette = require('marionette');
|
||||
var IndexerCollection = require('./IndexerCollection');
|
||||
var CollectionView = require('./IndexerCollectionView');
|
||||
var OptionsView = require('./Options/IndexerOptionsView');
|
||||
var RestrictionCollection = require('./Restriction/RestrictionCollection');
|
||||
var RestrictionCollectionView = require('./Restriction/RestrictionCollectionView');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
template : 'Settings/Indexers/IndexerLayoutTemplate',
|
||||
|
||||
regions : {
|
||||
indexers : '#x-indexers-region',
|
||||
indexerOptions : '#x-indexer-options-region',
|
||||
restriction : '#x-restriction-region'
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
this.indexersCollection = new IndexerCollection();
|
||||
this.indexersCollection.fetch();
|
||||
|
||||
this.restrictionCollection = new RestrictionCollection();
|
||||
this.restrictionCollection.fetch();
|
||||
},
|
||||
|
||||
onShow : function() {
|
||||
this.indexers.show(new CollectionView({ collection : this.indexersCollection }));
|
||||
this.indexerOptions.show(new OptionsView({ model : this.model }));
|
||||
this.restriction.show(new RestrictionCollectionView({ collection : this.restrictionCollection }));
|
||||
}
|
||||
});
|
@ -0,0 +1,5 @@
|
||||
<div id="x-indexers-region"></div>
|
||||
<div class="form-horizontal">
|
||||
<div id="x-indexer-options-region"></div>
|
||||
<div id="x-restriction-region"></div>
|
||||
</div>
|
@ -0,0 +1,13 @@
|
||||
var Backbone = require('backbone');
|
||||
var NetImportModel = require('./NetImportModel');
|
||||
|
||||
module.exports = Backbone.Collection.extend({
|
||||
model : NetImportModel,
|
||||
url : window.NzbDrone.ApiRoot + '/netimport',
|
||||
|
||||
comparator : function(left, right, collection) {
|
||||
var result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
var ProviderSettingsModelBase = require('../ProviderSettingsModelBase');
|
||||
|
||||
module.exports = ProviderSettingsModelBase.extend({});
|
@ -0,0 +1,7 @@
|
||||
var SettingsModelBase = require('../SettingsModelBase');
|
||||
|
||||
module.exports = SettingsModelBase.extend({
|
||||
url : window.NzbDrone.ApiRoot + '/config/netimport',
|
||||
successMessage : 'Net Import settings saved',
|
||||
errorMessage : 'Failed to save net import settings'
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
var Marionette = require('marionette');
|
||||
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Options/IndexerOptionsViewTemplate'
|
||||
});
|
||||
|
||||
AsModelBoundView.call(view);
|
||||
AsValidatedView.call(view);
|
||||
|
||||
module.exports = view;
|
@ -0,0 +1,40 @@
|
||||
<fieldset>
|
||||
<legend>Options</legend>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Minimum Age</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Usenet only: Minimum age in minutes of NZBs before they are grabbed. Use this to give new releases time to propagate to your usenet provider."/>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 col-sm-pull-1">
|
||||
<input type="number" min="0" name="minimumAge" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Retention</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Usenet only: Set to zero to set to unlimited"/>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 col-sm-pull-1">
|
||||
<input type="number" min="0" name="retention" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group advanced-setting">
|
||||
<label class="col-sm-3 control-label">RSS Sync Interval</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||
<i class="icon-sonarr-form-warning" title="This will apply to all indexers, please follow the rules set forth by them"/>
|
||||
<i class="icon-sonarr-form-info" title="Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)"/>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 col-sm-pull-1">
|
||||
<input type="number" name="rssSyncInterval" class="form-control" min="0" max="120"/>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
@ -0,0 +1,7 @@
|
||||
var Backbone = require('backbone');
|
||||
var RestrictionModel = require('./RestrictionModel');
|
||||
|
||||
module.exports = Backbone.Collection.extend({
|
||||
model : RestrictionModel,
|
||||
url : window.NzbDrone.ApiRoot + '/Restriction'
|
||||
});
|
@ -0,0 +1,26 @@
|
||||
var AppLayout = require('../../../AppLayout');
|
||||
var Marionette = require('marionette');
|
||||
var RestrictionItemView = require('./RestrictionItemView');
|
||||
var EditView = require('./RestrictionEditView');
|
||||
require('../../../Tags/TagHelpers');
|
||||
require('bootstrap');
|
||||
|
||||
module.exports = Marionette.CompositeView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionCollectionViewTemplate',
|
||||
itemViewContainer : '.x-rows',
|
||||
itemView : RestrictionItemView,
|
||||
|
||||
events : {
|
||||
'click .x-add' : '_addMapping'
|
||||
},
|
||||
|
||||
_addMapping : function() {
|
||||
var model = this.collection.create({ tags : [] });
|
||||
var view = new EditView({
|
||||
model : model,
|
||||
targetCollection : this.collection
|
||||
});
|
||||
|
||||
AppLayout.modalRegion.show(view);
|
||||
}
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
<fieldset class="advanced-setting">
|
||||
<legend>Restrictions</legend>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="rule-setting-list">
|
||||
<div class="rule-setting-header x-header hidden-xs">
|
||||
<div class="row">
|
||||
<span class="col-sm-4">Must Contain</span>
|
||||
<span class="col-sm-4">Must Not Contain</span>
|
||||
<span class="col-sm-3">Tags</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rows x-rows">
|
||||
</div>
|
||||
<div class="rule-setting-footer">
|
||||
<div class="pull-right">
|
||||
<span class="add-rule-setting-mapping">
|
||||
<i class="icon-sonarr-add x-add" title="Add new restriction" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
@ -0,0 +1,19 @@
|
||||
var vent = require('vent');
|
||||
var Marionette = require('marionette');
|
||||
|
||||
module.exports = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionDeleteViewTemplate',
|
||||
|
||||
events : {
|
||||
'click .x-confirm-delete' : '_delete'
|
||||
},
|
||||
|
||||
_delete : function() {
|
||||
this.model.destroy({
|
||||
wait : true,
|
||||
success : function() {
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>Delete Restriction</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Are you sure you want to delete this restriction?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">Cancel</button>
|
||||
<button class="btn btn-danger x-confirm-delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,55 @@
|
||||
var _ = require('underscore');
|
||||
var vent = require('vent');
|
||||
var AppLayout = require('../../../AppLayout');
|
||||
var Marionette = require('marionette');
|
||||
var DeleteView = require('./RestrictionDeleteView');
|
||||
var CommandController = require('../../../Commands/CommandController');
|
||||
var AsModelBoundView = require('../../../Mixins/AsModelBoundView');
|
||||
var AsValidatedView = require('../../../Mixins/AsValidatedView');
|
||||
var AsEditModalView = require('../../../Mixins/AsEditModalView');
|
||||
require('../../../Mixins/TagInput');
|
||||
require('bootstrap');
|
||||
require('bootstrap.tagsinput');
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionEditViewTemplate',
|
||||
|
||||
ui : {
|
||||
required : '.x-required',
|
||||
ignored : '.x-ignored',
|
||||
tags : '.x-tags'
|
||||
},
|
||||
|
||||
_deleteView : DeleteView,
|
||||
|
||||
initialize : function(options) {
|
||||
this.targetCollection = options.targetCollection;
|
||||
},
|
||||
|
||||
onRender : function() {
|
||||
this.ui.required.tagsinput({
|
||||
trimValue : true,
|
||||
tagClass : 'label label-success'
|
||||
});
|
||||
|
||||
this.ui.ignored.tagsinput({
|
||||
trimValue : true,
|
||||
tagClass : 'label label-danger'
|
||||
});
|
||||
|
||||
this.ui.tags.tagInput({
|
||||
model : this.model,
|
||||
property : 'tags'
|
||||
});
|
||||
},
|
||||
|
||||
_onAfterSave : function() {
|
||||
this.targetCollection.add(this.model, { merge : true });
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
}
|
||||
});
|
||||
|
||||
AsModelBoundView.call(view);
|
||||
AsValidatedView.call(view);
|
||||
AsEditModalView.call(view);
|
||||
module.exports = view;
|
@ -0,0 +1,60 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
{{#if id}}
|
||||
<h3>Edit Restriction</h3>
|
||||
{{else}}
|
||||
<h3>Add Restriction</h3>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="modal-body remotepath-mapping-modal">
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Must contain</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="The release must contain at least one of these terms (case insensitive)" />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" name="required" class="form-control x-required"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Must not contain</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="The release will be rejected if it contains one or more of terms (case insensitive)" />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" name="ignored" class="form-control x-ignored"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Tags</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Restrictions will apply to series with one or more matching tags. Leave blank to apply to all series" />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" class="form-control x-tags">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{#if id}}
|
||||
<button class="btn btn-danger pull-left x-delete">Delete</button>
|
||||
{{/if}}
|
||||
|
||||
<button class="btn" data-dismiss="modal">Cancel</button>
|
||||
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary x-save">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,28 @@
|
||||
var AppLayout = require('../../../AppLayout');
|
||||
var Marionette = require('marionette');
|
||||
var EditView = require('./RestrictionEditView');
|
||||
|
||||
module.exports = Marionette.ItemView.extend({
|
||||
template : 'Settings/Indexers/Restriction/RestrictionItemViewTemplate',
|
||||
className : 'row',
|
||||
|
||||
ui : {
|
||||
tags : '.x-tags'
|
||||
},
|
||||
|
||||
events : {
|
||||
'click .x-edit' : '_edit'
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
this.listenTo(this.model, 'sync', this.render);
|
||||
},
|
||||
|
||||
_edit : function() {
|
||||
var view = new EditView({
|
||||
model : this.model,
|
||||
targetCollection : this.model.collection
|
||||
});
|
||||
AppLayout.modalRegion.show(view);
|
||||
}
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
<div class="col-sm-4">
|
||||
{{genericTagDisplay required 'label label-success'}}
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
{{genericTagDisplay ignored 'label label-danger'}}
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
{{tagDisplay tags}}
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<div class="pull-right"><i class="icon-sonarr-edit x-edit" title="" data-original-title="Edit"></i></div>
|
||||
</div>
|
@ -0,0 +1,4 @@
|
||||
var $ = require('jquery');
|
||||
var DeepModel = require('backbone.deepmodel');
|
||||
|
||||
module.exports = DeepModel.extend({});
|
@ -0,0 +1,33 @@
|
||||
@import "../../Shared/Styles/clickable.less";
|
||||
|
||||
.indexer-list {
|
||||
li {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.indexer-item {
|
||||
|
||||
.clickable;
|
||||
|
||||
width: 290px;
|
||||
height: 90px;
|
||||
padding: 10px 15px;
|
||||
|
||||
&.add-card {
|
||||
.center {
|
||||
margin-top: -3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-overflow {
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
.add-indexer {
|
||||
li.add-thingy-item {
|
||||
width: 33%;
|
||||
}
|
||||
}
|
@ -1,49 +1,51 @@
|
||||
<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>
|
||||
<li><a href="#notifications" class="x-notifications-tab no-router">Connect</a></li>
|
||||
<li><a href="#metadata" class="x-metadata-tab no-router">Metadata</a></li>
|
||||
<li><a href="#general" class="x-general-tab no-router">General</a></li>
|
||||
<li><a href="#ui" class="x-ui-tab no-router">UI</a></li>
|
||||
<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>
|
||||
<li><a href="#net-import" class="x-net-import-tab no-router">Net Import</a></li>
|
||||
<li><a href="#notifications" class="x-notifications-tab no-router">Connect</a></li>
|
||||
<li><a href="#metadata" class="x-metadata-tab no-router">Metadata</a></li>
|
||||
<li><a href="#general" class="x-general-tab no-router">General</a></li>
|
||||
<li><a href="#ui" class="x-ui-tab no-router">UI</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="row settings-controls">
|
||||
<div class="col-sm-4 col-sm-offset-7 col-md-3 col-md-offset-8">
|
||||
<div class="advanced-settings-toggle">
|
||||
<span class="help-inline-checkbox hidden-xs">
|
||||
Advanced Settings
|
||||
</span>
|
||||
<label class="checkbox toggle well">
|
||||
<input type="checkbox" class="x-advanced-settings"/>
|
||||
<p>
|
||||
<span>Shown</span>
|
||||
<span>Hidden</span>
|
||||
</p>
|
||||
<div class="btn btn-warning slide-button"/>
|
||||
</label>
|
||||
<span class="help-inline-checkbox hidden-sm hidden-md hidden-lg">
|
||||
Advanced Settings
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-1 col-md-1">
|
||||
<button class="btn btn-primary x-save-settings">Save</button>
|
||||
</div>
|
||||
<div class="col-sm-4 col-sm-offset-7 col-md-3 col-md-offset-8">
|
||||
<div class="advanced-settings-toggle">
|
||||
<span class="help-inline-checkbox hidden-xs">
|
||||
Advanced Settings
|
||||
</span>
|
||||
<label class="checkbox toggle well">
|
||||
<input type="checkbox" class="x-advanced-settings"/>
|
||||
<p>
|
||||
<span>Shown</span>
|
||||
<span>Hidden</span>
|
||||
</p>
|
||||
<div class="btn btn-warning slide-button"/>
|
||||
</label>
|
||||
<span class="help-inline-checkbox hidden-sm hidden-md hidden-lg">
|
||||
Advanced Settings
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-1 col-md-1">
|
||||
<button class="btn btn-primary x-save-settings">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<div class="tab-pane" id="notifications"></div>
|
||||
<div class="tab-pane" id="metadata"></div>
|
||||
<div class="tab-pane" id="general"></div>
|
||||
<div class="tab-pane" id="ui"></div>
|
||||
<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>
|
||||
<div class="tab-pane" id="net-import"></div>
|
||||
<div class="tab-pane" id="notifications"></div>
|
||||
<div class="tab-pane" id="metadata"></div>
|
||||
<div class="tab-pane" id="general"></div>
|
||||
<div class="tab-pane" id="ui"></div>
|
||||
</div>
|
||||
|
||||
<div id="loading-region"></div>
|
||||
<div id="loading-region"></div>
|
||||
|
Loading…
Reference in new issue