| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| define([ |
| "app", |
| "api", |
| "addons/fauxton/components", |
| "addons/replication/resources" |
| ], |
| function(app, FauxtonAPI, Components, replication) { |
| var View = {}, |
| Events ={}, |
| pollingInfo ={ |
| rate: 5, |
| intervalId: null |
| }; |
| |
| _.extend(Events, Backbone.Events); |
| |
| // NOTES: http://wiki.apache.org/couchdb/Replication |
| |
| // Replication form view is huge |
| // ----------------------------------- |
| // afterRender: autocomplete on the target input field |
| // beforeRender: add the status table |
| // disableFields: disable non active fields on submit |
| // enableFields: enable field when radio btns are clicked |
| // establish: get the DB list for autocomplete |
| // formValidation: make sure fields aren't empty |
| // showProgress: make a call to active_tasks model and show only replication types. Poll every 5 seconds. (make this it's own view) |
| // startReplication: saves to the model, starts replication |
| // submit: form submit handler |
| // swapFields: change to and from target |
| // toggleAdvancedOptions: toggle advanced |
| |
| View.ReplicationForm = FauxtonAPI.View.extend({ |
| template: "addons/replication/templates/form", |
| events: { |
| "submit #replication": "validate", |
| "click .btn-group .btn": "showFields", |
| "click .swap": "swapFields", |
| "click .options": "toggleAdvancedOptions" |
| }, |
| initialize: function(options){ |
| this.status = options.status; |
| this.selectedDB = options.selectedDB; |
| this.newRepModel = new replication.Replicate({}); |
| }, |
| afterRender: function(){ |
| this.dbSearchTypeahead = new Components.DbSearchTypeahead({ |
| dbLimit: 30, |
| el: "input#to_name" |
| }); |
| |
| this.dbSearchTypeahead.render(); |
| |
| }, |
| |
| beforeRender: function(){ |
| this.insertView("#replicationStatus", new View.ReplicationList({ |
| collection: this.status |
| })); |
| }, |
| cleanup: function(){ |
| clearInterval(pollingInfo.intervalId); |
| }, |
| enableFields: function(){ |
| this.$el.find('input','select').attr('disabled',false); |
| }, |
| disableFields: function(){ |
| this.$el.find('input:hidden','select:hidden').attr('disabled',true); |
| }, |
| showFields: function(e){ |
| var $currentTarget = this.$(e.currentTarget), |
| targetVal = $currentTarget.val(); |
| |
| if (targetVal === "local"){ |
| $currentTarget.parents('.form_set').addClass('local'); |
| }else{ |
| $currentTarget.parents('.form_set').removeClass('local'); |
| } |
| }, |
| establish: function(){ |
| return [ this.collection.fetch(), this.status.fetch()]; |
| }, |
| validate: function(e){ |
| e.preventDefault(); |
| var notification; |
| if (this.formValidation()){ |
| notification = FauxtonAPI.addNotification({ |
| msg: "Please enter every field.", |
| type: "error", |
| clear: true |
| }); |
| }else if (this.$('input#to_name').is(':visible') && !this.$('input[name=create_target]').is(':checked')){ |
| var alreadyExists = this.collection.where({"name":this.$('input#to_name').val()}); |
| if (alreadyExists.length === 0){ |
| notification = FauxtonAPI.addNotification({ |
| msg: "This database doesn't exist. Check create target if you want to create it.", |
| type: "error", |
| clear: true |
| }); |
| } |
| }else{ |
| this.submit(e); |
| } |
| }, |
| formValidation: function(e){ |
| var $remote = this.$el.find('input:visible'), |
| error = false; |
| for(var i=0; i<$remote.length; i++){ |
| if ($remote[i].value =="http://" || $remote[i].value ===""){ |
| error = true; |
| } |
| } |
| return error; |
| }, |
| serialize: function(){ |
| return { |
| databases: this.collection.toJSON(), |
| selectedDB: this.selectedDB |
| }; |
| }, |
| startReplication: function(json){ |
| var that = this; |
| this.newRepModel.save(json,{ |
| success: function(resp){ |
| var notification = FauxtonAPI.addNotification({ |
| msg: "Replication from "+resp.get('source')+" to "+ resp.get('target')+" has begun.", |
| type: "success", |
| clear: true |
| }); |
| that.updateButtonText(false); |
| Events.trigger('update:tasks'); |
| }, |
| error: function(model, xhr, options){ |
| var errorMessage = JSON.parse(xhr.responseText); |
| var notification = FauxtonAPI.addNotification({ |
| msg: errorMessage.reason, |
| type: "error", |
| clear: true |
| }); |
| that.updateButtonText(false); |
| } |
| }); |
| this.enableFields(); |
| }, |
| updateButtonText: function(wait){ |
| var $button = this.$('#replication button[type=submit]'); |
| if(wait){ |
| $button.text('Starting replication...').attr('disabled', true); |
| } else { |
| $button.text('Replication').attr('disabled', false); |
| } |
| }, |
| submit: function(e){ |
| this.disableFields(); |
| var formJSON = {}; |
| _.map(this.$(e.currentTarget).serializeArray(), function(formData){ |
| if(formData.value !== ''){ |
| formJSON[formData.name] = (formData.value ==="true"? true: formData.value.replace(/\s/g, '').toLowerCase()); |
| } |
| }); |
| |
| this.updateButtonText(true); |
| this.startReplication(formJSON); |
| }, |
| swapFields: function(e){ |
| e.preventDefault(); |
| //WALL O' VARIABLES |
| var $fromSelect = this.$('#from_name'), |
| $toSelect = this.$('#to_name'), |
| $toInput = this.$('#to_url'), |
| $fromInput = this.$('#from_url'), |
| fromSelectVal = $fromSelect.val(), |
| fromInputVal = $fromInput.val(), |
| toSelectVal = $toSelect.val(), |
| toInputVal = $toInput.val(); |
| |
| $fromSelect.val(toSelectVal); |
| $toSelect.val(fromSelectVal); |
| |
| $fromInput.val(toInputVal); |
| $toInput.val(fromInputVal); |
| } |
| }); |
| |
| |
| View.ReplicationList = FauxtonAPI.View.extend({ |
| tagName: "ul", |
| initialize: function(){ |
| Events.bind('update:tasks', this.establish, this); |
| this.listenTo(this.collection, "reset", this.render); |
| this.$el.prepend("<li class='header'><h4>Active Replication Tasks</h4></li>"); |
| }, |
| establish: function(){ |
| return [this.collection.fetch({reset: true})]; |
| }, |
| setPolling: function(){ |
| var that = this; |
| this.cleanup(); |
| pollingInfo.intervalId = setInterval(function() { |
| that.establish(); |
| }, pollingInfo.rate*1000); |
| }, |
| cleanup: function(){ |
| clearInterval(pollingInfo.intervalId); |
| }, |
| beforeRender: function(){ |
| this.collection.forEach(function(item) { |
| this.insertView(new View.replicationItem({ |
| model: item |
| })); |
| }, this); |
| }, |
| showHeader: function(){ |
| if (this.collection.length > 0){ |
| this.$el.parent().addClass('showHeader'); |
| } else { |
| this.$el.parent().removeClass('showHeader'); |
| } |
| }, |
| afterRender: function(){ |
| this.showHeader(); |
| this.setPolling(); |
| } |
| }); |
| |
| //make this a table row item. |
| View.replicationItem = FauxtonAPI.View.extend({ |
| tagName: "li", |
| className: "row", |
| template: "addons/replication/templates/progress", |
| events: { |
| "click .cancel": "cancelReplication" |
| }, |
| initialize: function(){ |
| this.newRepModel = new replication.Replicate({}); |
| }, |
| establish: function(){ |
| return [this.model.fetch()]; |
| }, |
| cancelReplication: function(e){ |
| //need to pass "cancel": true with source & target |
| var $currentTarget = this.$(e.currentTarget), |
| repID = $currentTarget.attr('data-rep-id'); |
| this.newRepModel.save({ |
| "replication_id": repID, |
| "cancel": true |
| }, |
| { |
| success: function(model, xhr, options){ |
| var notification = FauxtonAPI.addNotification({ |
| msg: "Replication stopped.", |
| type: "success", |
| clear: true |
| }); |
| }, |
| error: function(model, xhr, options){ |
| var errorMessage = JSON.parse(xhr.responseText); |
| var notification = FauxtonAPI.addNotification({ |
| msg: errorMessage.reason, |
| type: "error", |
| clear: true |
| }); |
| } |
| }); |
| }, |
| afterRender: function(){ |
| if (this.model.get('continuous')){ |
| this.$el.addClass('continuous'); |
| } |
| }, |
| serialize: function(){ |
| return { |
| progress: this.model.get('progress'), |
| target: this.model.get('target'), |
| source: this.model.get('source'), |
| continuous: this.model.get('continuous'), |
| repid: this.model.get('replication_id') |
| }; |
| } |
| }); |
| |
| return View; |
| }); |