summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarren Smith <garren.smith@gmail.com>2013-06-11 16:39:35 +0200
committerGarren Smith <garren.smith@gmail.com>2013-07-02 10:45:41 +0200
commit7a7db425f60354da2a49fcd25473e839d3bb50c9 (patch)
tree8350f2388b2c80ec3c9b7a1c57fc624918488c95
parentc86d73f03a640b50efe46da79baeba482db12b08 (diff)
downloadcouchdb-1828-duplicate-doc.tar.gz
Fauxton Duplicate Document1828-duplicate-doc
Duplicates the current document using Couchdb's COPY api.
-rw-r--r--src/fauxton/app/modules/documents/resources.js13
-rw-r--r--src/fauxton/app/modules/documents/routes.js22
-rw-r--r--src/fauxton/app/modules/documents/views.js138
-rw-r--r--src/fauxton/app/templates/documents/doc_field_editor_tabs.html1
-rw-r--r--src/fauxton/app/templates/documents/duplicate_doc_modal.html36
5 files changed, 180 insertions, 30 deletions
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 8fc384e17..bece38677 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -67,6 +67,10 @@ function(app, FauxtonAPI) {
return views && _.keys(views).length > 0;
},
+ hasAttachments: function () {
+ return !!this.get('_attachments');
+ },
+
getDdocView: function(view) {
if (!this.isDdoc() || !this.hasViews()) return false;
@@ -109,7 +113,6 @@ function(app, FauxtonAPI) {
var doc = this.get('doc');
if (doc) {
- console.log('DOC', doc);
return new Documents.Doc(doc, {database: this.database});
}
@@ -161,6 +164,14 @@ function(app, FauxtonAPI) {
var data = this.get("doc") ? this.get("doc") : this;
return JSON.stringify(data, null, " ");
+ },
+
+ copy: function (copyId) {
+ return $.ajax({
+ type: 'COPY',
+ url: '/' + this.database.id + '/' + this.id,
+ headers: {Destination: copyId}
+ });
}
});
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index a49fa9169..b06b9115f 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -52,7 +52,8 @@ function(app, FauxtonAPI, Documents, Databases) {
},
events: {
- "route:reRenderDoc": "reRenderDoc"
+ "route:reRenderDoc": "reRenderDoc",
+ "route:duplicateDoc": "duplicateDoc"
},
crumbs: function() {
@@ -73,7 +74,6 @@ function(app, FauxtonAPI, Documents, Databases) {
reRenderDoc: function () {
this.docView.forceRender();
- console.log('rerender');
},
field_editor: function(events) {
@@ -83,6 +83,24 @@ function(app, FauxtonAPI, Documents, Databases) {
}));
},
+ duplicateDoc: function (newId) {
+ var doc = this.doc,
+ docView = this.docView,
+ database = this.database;
+
+ doc.copy(newId).then(function () {
+ doc.set({_id: newId});
+ docView.forceRender();
+ FauxtonAPI.navigate('/database/' + database.id + '/' + newId, {trigger: true});
+ }, function (error) {
+ var errorMsg = "Could not duplicate document, reason: " + error.responseText + ".";
+ FauxtonAPI.addNotification({
+ msg: errorMsg,
+ type: "error"
+ });
+ });
+ },
+
apiUrl: function() {
return this.doc.url();
}
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index 59e3b7dc1..c0098cdd6 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -143,7 +143,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
event.preventDefault();
var docRev = this.model.get('_rev'),
- $form = this.$('#file-upload');
+ $form = this.$('#file-upload');
if (!docRev) {
return this.set_error_msg('The document needs to be saved before adding an attachment.');
@@ -166,7 +166,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
success: function (resp) {
var hideModal = this.hideModal,
- $form = this.$('#file-upload');
+ $form = this.$('#file-upload');
FauxtonAPI.triggerRouteEvent('reRenderDoc');
//slight delay to make this transistion a little more fluid and less jumpy
@@ -181,7 +181,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
},
beforeSend: function () {
- this.$('.progress').removeClass('hide');
+ this.$('.progress').removeClass('hide');
},
showModal: function () {
@@ -216,6 +216,74 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
}
});
+ Views.DuplicateDocModal = FauxtonAPI.View.extend({
+ template: "templates/documents/duplicate_doc_modal",
+
+ initialize: function () {
+ _.bindAll(this);
+ },
+
+ events: {
+ "click #duplicate-btn":"duplicate"
+
+ },
+
+ duplicate: function (event) {
+ event.preventDefault();
+ var newId = this.$('#dup-id').val();
+
+ this.hideModal();
+ FauxtonAPI.triggerRouteEvent('duplicateDoc', newId);
+ },
+
+ _showModal: function () {
+ this.$('.bar').css({width: '0%'});
+ this.$('.progress').addClass('hide');
+ this.clear_error_msg();
+ this.$('.modal').modal();
+ // hack to get modal visible
+ $('.modal-backdrop').css('z-index',1025);
+ },
+
+ showModal: function () {
+ var showModal = this._showModal,
+ setDefaultIdValue = this.setDefaultIdValue,
+ uuid = new FauxtonAPI.UUID();
+
+ uuid.fetch().then(function () {
+ setDefaultIdValue(uuid.next());
+ showModal();
+ });
+ },
+
+ setDefaultIdValue: function (id) {
+ this.$('#dup-id').val(id);
+ },
+
+ hideModal: function () {
+ this.$('.modal').modal('hide');
+ },
+
+ set_error_msg: function (msg) {
+ var text;
+ if (typeof(msg) == 'string') {
+ text = msg;
+ } else {
+ text = JSON.parse(msg.responseText).reason;
+ }
+ this.$('#modal-error').text(text).removeClass('hide');
+ },
+
+ clear_error_msg: function () {
+ this.$('#modal-error').text(' ').addClass('hide');
+ },
+
+ serialize: function () {
+ return this.model.toJSON();
+ }
+
+ });
+
Views.FieldEditorTabs = FauxtonAPI.View.extend({
template: "templates/documents/doc_field_editor_tabs",
@@ -252,18 +320,19 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
beforeRender: function () {
this.uploadModal = this.setView('#upload-modal', new Views.UploadModal({model: this.model}));
this.uploadModal.render();
+
+ this.duplicateModal = this.setView('#duplicate-modal', new Views.DuplicateDocModal({model: this.model}));
+ this.duplicateModal.render();
},
-
+
upload: function (event) {
event.preventDefault();
this.uploadModal.showModal();
},
duplicate: function(event) {
- FauxtonAPI.addNotification({
- type: "warning",
- msg: "Duplicate functionality coming soon."
- });
+ event.preventDefault();
+ this.duplicateModal.showModal();
},
updateSelected: function (selected) {
@@ -507,12 +576,15 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
},
saveDoc: function(event) {
- var json, notification, that = this;
- if (this.hasValidCode()) {
- json = JSON.parse(this.editor.getValue());
- this.model.clear({silent:true});
- this.model.set(json);
+ var json, notification,
+ that = this,
+ validDoc = this.getDocFromEditor();
+
+ if (validDoc) {
+ this.getDocFromEditor();
+
notification = FauxtonAPI.addNotification({msg: "Saving document."});
+
this.model.save().then(function () {
FauxtonAPI.navigate('/database/' + that.database.id + '/' + that.model.id);
}).fail(function(xhr) {
@@ -532,6 +604,18 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
}
},
+ getDocFromEditor: function () {
+ if (!this.hasValidCode()) {
+ return false;
+ }
+
+ json = JSON.parse(this.editor.getValue());
+ this.model.clear({silent:true});
+ this.model.set(json);
+
+ return this.model;
+ },
+
hasValidCode: function() {
return JSHINT(this.editor.getValue()) !== false;
},
@@ -763,10 +847,10 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
if (!confirm('Are you sure you want to delete this view?')) {return;}
var that = this,
- promise,
- viewName = this.$('#index-name').val();
- ddocName = this.$('#ddoc :selected').val(),
- ddoc = this.getCurrentDesignDoc();
+ promise,
+ viewName = this.$('#index-name').val();
+ ddocName = this.$('#ddoc :selected').val(),
+ ddoc = this.getCurrentDesignDoc();
ddoc.removeDdocView(viewName);
@@ -788,8 +872,8 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
if (this.newView) { return alert('Please save this new view before querying it.'); }
var paramInfo = this.queryParams(),
- errorParams = paramInfo.errorParams,
- params = paramInfo.params;
+ errorParams = paramInfo.errorParams,
+ params = paramInfo.params;
if (_.any(errorParams)) {
_.map(errorParams, function(param) {
@@ -858,9 +942,9 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
previewView: function(event) {
var that = this,
- mapVal = this.mapEditor.getValue(),
- reduceVal = this.reduceVal(),
- paramsArr = this.queryParams().params;
+ mapVal = this.mapEditor.getValue(),
+ reduceVal = this.reduceVal(),
+ paramsArr = this.queryParams().params;
var params = _.reduce(paramsArr, function (params, param) {
params[param.name] = param.value;
@@ -903,10 +987,10 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
if (this.hasValidCode()) {
var mapVal = this.mapEditor.getValue(),
- reduceVal = this.reduceVal(),
- viewName = this.$('#index-name').val(),
- ddoc = this.getCurrentDesignDoc(),
- ddocName = ddoc.id;
+ reduceVal = this.reduceVal(),
+ viewName = this.$('#index-name').val(),
+ ddoc = this.getCurrentDesignDoc(),
+ ddocName = ddoc.id;
this.viewName = viewName;
@@ -1287,7 +1371,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint) {
model.fetch();
}, this.refreshTime);
},
-
+
stopRefreshInterval: function () {
clearInterval(this.intervalId);
},
diff --git a/src/fauxton/app/templates/documents/doc_field_editor_tabs.html b/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
index 01cb8a902..fcc2b53e6 100644
--- a/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
+++ b/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
@@ -27,3 +27,4 @@ the License.
</ul>
<div id="upload-modal"> </div>
+<div id="duplicate-modal"> </div>
diff --git a/src/fauxton/app/templates/documents/duplicate_doc_modal.html b/src/fauxton/app/templates/documents/duplicate_doc_modal.html
new file mode 100644
index 000000000..dba8d44b8
--- /dev/null
+++ b/src/fauxton/app/templates/documents/duplicate_doc_modal.html
@@ -0,0 +1,36 @@
+<!--
+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.
+-->
+
+<div class="modal hide fade">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+ <h3>Duplicate Document</h3>
+ </div>
+ <div class="modal-body">
+ <div id="modal-error" class="hide alert alert-error"/>
+ <form id="file-upload" class="form" method="post">
+ <p class="help-block">
+ Set new documents ID:
+ </p>
+ <input id="dup-id" type="text" class="input-xlarge">
+ </form>
+
+ </div>
+ <div class="modal-footer">
+ <a href="#" data-dismiss="modal" class="btn">Cancel</a>
+ <a href="#" id="duplicate-btn" class="btn btn-primary">Duplicate</a>
+ </div>
+</div>
+
+