New: Added global Remote Path mapping table to replace individual Local Category Path settings.

This commit is contained in:
Taloth Saldono
2014-09-11 22:24:00 +02:00
parent 8281063698
commit 525f1aa9dd
36 changed files with 904 additions and 137 deletions

View File

@@ -4,9 +4,11 @@ define([
'marionette',
'Settings/DownloadClient/DownloadClientCollection',
'Settings/DownloadClient/DownloadClientCollectionView',
'Settings/DownloadClient/DownloadHandling/DownloadHandlingView',
'Settings/DownloadClient/DroneFactory/DroneFactoryView',
'Settings/DownloadClient/DownloadHandling/DownloadHandlingView'
], function (Marionette, DownloadClientCollection, CollectionView, DroneFactoryView, DownloadHandlingView) {
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingCollection',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingCollectionView'
], function (Marionette, DownloadClientCollection, DownloadClientCollectionView, DownloadHandlingView, DroneFactoryView, RemotePathMappingCollection, RemotePathMappingCollectionView) {
return Marionette.Layout.extend({
template : 'Settings/DownloadClient/DownloadClientLayoutTemplate',
@@ -14,18 +16,22 @@ define([
regions: {
downloadClients : '#x-download-clients-region',
downloadHandling : '#x-download-handling-region',
droneFactory : '#x-dronefactory-region'
droneFactory : '#x-dronefactory-region',
remotePathMappings : '#x-remotepath-mapping-region'
},
initialize: function () {
this.downloadClientsCollection = new DownloadClientCollection();
this.downloadClientsCollection.fetch();
this.remotePathMappingCollection = new RemotePathMappingCollection();
this.remotePathMappingCollection.fetch();
},
onShow: function () {
this.downloadClients.show(new CollectionView({ collection: this.downloadClientsCollection }));
this.downloadClients.show(new DownloadClientCollectionView({ collection: this.downloadClientsCollection }));
this.downloadHandling.show(new DownloadHandlingView({ model: this.model }));
this.droneFactory.show(new DroneFactoryView({ model: this.model }));
this.remotePathMappings.show(new RemotePathMappingCollectionView({ collection: this.remotePathMappingCollection }));
}
});
});

View File

@@ -1,6 +1,6 @@
<div id="x-download-clients-region"></div>
<div class="form-horizontal">
<div id="x-download-handling-region"></div>
<div id="x-dronefactory-region"></div>
<div id="x-remotepath-mapping-region"></div>
</div>

View File

@@ -0,0 +1,11 @@
'use strict';
define([
'backbone',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingModel'
], function (Backbone, RemotePathMappingModel) {
return Backbone.Collection.extend({
model : RemotePathMappingModel,
url : window.NzbDrone.ApiRoot + '/remotePathMapping'
});
});

View File

@@ -0,0 +1,28 @@
'use strict';
define([
'AppLayout',
'marionette',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingItemView',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingEditView',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingModel',
'bootstrap'
], function (AppLayout, Marionette, RemotePathMappingItemView, EditView, RemotePathMappingModel) {
return Marionette.CompositeView.extend({
template : 'Settings/DownloadClient/RemotePathMapping/RemotePathMappingCollectionViewTemplate',
itemViewContainer : '.x-rows',
itemView : RemotePathMappingItemView,
events: {
'click .x-add' : '_addMapping'
},
_addMapping: function() {
var model = new RemotePathMappingModel();
model.collection = this.collection;
var view = new EditView({ model: model, targetCollection: this.collection});
AppLayout.modalRegion.show(view);
}
});
});

View File

@@ -0,0 +1,24 @@
<fieldset class="advanced-setting">
<legend>Remote Path Mappings</legend>
<div class="col-md-12">
<div id="remotepath-mapping-list">
<div class="remotepath-header x-header hidden-xs">
<div class="row">
<span class="col-sm-2">Host</span>
<span class="col-sm-5">Remote Path</span>
<span class="col-sm-4">Local Path</span>
</div>
</div>
<div class="rows x-rows">
</div>
<div class="remotepath-footer">
<div class="pull-right">
<span class="add-remotepath-mapping">
<i class="icon-nd-add x-add" title="Add new mapping" />
</span>
</div>
</div>
</div>
</div>
</fieldset>

View File

@@ -0,0 +1,23 @@
'use strict';
define([
'vent',
'marionette'
], function (vent, Marionette) {
return Marionette.ItemView.extend({
template: 'Settings/DownloadClient/RemotePathMapping/RemotePathMappingDeleteViewTemplate',
events: {
'click .x-confirm-delete': '_delete'
},
_delete: function () {
this.model.destroy({
wait : true,
success: function () {
vent.trigger(vent.Commands.CloseModalCommand);
}
});
}
});
});

View File

@@ -0,0 +1,13 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>Delete Mapping</h3>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the mapping for '{{localPath}}'?</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>

View File

@@ -0,0 +1,51 @@
'use strict';
define([
'underscore',
'vent',
'AppLayout',
'marionette',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingDeleteView',
'Commands/CommandController',
'Mixins/AsModelBoundView',
'Mixins/AsValidatedView',
'Mixins/AsEditModalView',
'Mixins/AutoComplete',
'bootstrap'
], function (_, vent, AppLayout, Marionette, DeleteView, CommandController, AsModelBoundView, AsValidatedView, AsEditModalView) {
var view = Marionette.ItemView.extend({
template : 'Settings/DownloadClient/RemotePathMapping/RemotePathMappingEditViewTemplate',
ui : {
path : '.x-path',
modalBody : '.modal-body'
},
_deleteView: DeleteView,
initialize : function (options) {
this.targetCollection = options.targetCollection;
},
onShow : function () {
//Hack to deal with modals not overflowing
if (this.ui.path.length > 0) {
this.ui.modalBody.addClass('modal-overflow');
}
this.ui.path.autoComplete('/directories');
},
_onAfterSave : function () {
this.targetCollection.add(this.model, { merge : true });
vent.trigger(vent.Commands.CloseModalCommand);
}
});
AsModelBoundView.call(view);
AsValidatedView.call(view);
AsEditModalView.call(view);
return view;
});

View File

@@ -0,0 +1,63 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
{{#if id}}
<h3>Edit Mapping</h3>
{{else}}
<h3>Add Mapping</h3>
{{/if}}
</div>
<div class="modal-body remotepath-mapping-modal">
<div class="form-horizontal">
<div>
<p>Use this feature if you have a remotely running Download Client. NzbDrone will use the information provided to translate the paths provided by the Download Client API to something NzbDrone can access and import.</p>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Host</label>
<div class="col-sm-1 col-sm-push-3 help-inline">
<i class="icon-nd-form-info" title="Host you specified for the remote Download Client." />
</div>
<div class="col-sm-3 col-sm-pull-1">
<input type="text" name="host" class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Remote Path</label>
<div class="col-sm-1 col-sm-push-5 help-inline">
<i class="icon-nd-form-info" title="Root path to the directory that the Download Client accesses." />
</div>
<div class="col-sm-5 col-sm-pull-1">
<input type="text" name="remotePath" class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Local Path</label>
<div class="col-sm-1 col-sm-push-5 help-inline">
<i class="icon-nd-form-info" title="Path that NzbDrone should use to access the same directory remotely." />
</div>
<div class="col-sm-5 col-sm-pull-1">
<input type="text" name="localPath" class="form-control x-path"/>
</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>

View File

@@ -0,0 +1,26 @@
'use strict';
define([
'AppLayout',
'marionette',
'Settings/DownloadClient/RemotePathMapping/RemotePathMappingEditView'
], function (AppLayout, Marionette, EditView) {
return Marionette.ItemView.extend({
template : 'Settings/DownloadClient/RemotePathMapping/RemotePathMappingItemViewTemplate',
className : 'row',
events: {
'click .x-edit' : '_editMapping'
},
initialize: function () {
this.listenTo(this.model, 'sync', this.render);
},
_editMapping: function() {
var view = new EditView({ model: this.model, targetCollection: this.model.collection});
AppLayout.modalRegion.show(view);
}
});
});

View File

@@ -0,0 +1,12 @@
<span class="col-sm-2">
<div>{{host}}</div>
</span>
<span class="col-sm-5">
<div>{{remotePath}}</div>
</span>
<span class="col-sm-4">
<div>{{localPath}}</div>
</span>
<span class="col-sm-1">
<div class="pull-right"><i class="icon-nd-edit x-edit" title="" data-original-title="Edit Mapping"></i></div>
</span>

View File

@@ -0,0 +1,10 @@
'use strict';
define([
'jquery',
'backbone.deepmodel'
], function ($, DeepModel) {
return DeepModel.DeepModel.extend({
});
});

View File

@@ -30,4 +30,31 @@
li.add-thingy-item {
width: 33%;
}
}
.add-remotepath-mapping {
cursor: pointer;
font-size: 14px;
text-align: center;
display: inline-block;
padding: 2px 6px;
i {
cursor: pointer;
}
}
#remotepath-mapping-list {
.remotepath-header .row {
font-weight: bold;
line-height: 40px;
}
.rows .row {
line-height : 30px;
border-top : 1px solid #ddd;
vertical-align : middle;
padding : 5px;
}
}

View File

@@ -10,7 +10,7 @@ define(
return Marionette.CompositeView.extend({
template: 'Settings/Quality/Definition/QualityDefinitionCollectionTemplate',
itemViewContainer: ".x-rows",
itemViewContainer: '.x-rows',
itemView: QualityDefinitionView
});