Updated Branches:
  refs/heads/master b45574065 -> a5b888bb8

Fauxton Duplicate Document
Duplicates the current document using Couchdb's COPY api.

Resolves COUCHDB-1828

set notification message


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/a5b888bb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/a5b888bb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/a5b888bb

Branch: refs/heads/master
Commit: a5b888bb8e2dd68d1149bcb6d5f62028aa74d7df
Parents: b455740
Author: Garren Smith <garren.sm...@gmail.com>
Authored: Tue Jun 11 16:39:35 2013 +0200
Committer: Garren Smith <garren.sm...@gmail.com>
Committed: Thu Jul 25 09:43:14 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/resources.js  |  12 ++
 src/fauxton/app/modules/documents/routes.js     |  25 +++-
 src/fauxton/app/modules/documents/views.js      | 128 +++++++++++++++----
 .../documents/doc_field_editor_tabs.html        |   1 +
 .../documents/duplicate_doc_modal.html          |  36 ++++++
 5 files changed, 179 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/a5b888bb/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js 
b/src/fauxton/app/modules/documents/resources.js
index ef4e1a0..bece386 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;
 
@@ -160,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}
+      });
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/a5b888bb/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js 
b/src/fauxton/app/modules/documents/routes.js
index caad827..f680b41 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() {
@@ -82,6 +83,28 @@ 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});
+        FauxtonAPI.addNotification({
+          msg: "Document has been duplicated."
+        });
+
+      }, function (error) {
+        var errorMsg = "Could not duplicate document, reason: " + 
error.responseText + ".";
+        FauxtonAPI.addNotification({
+          msg: errorMsg,
+          type: "error"
+        });
+      });
+    },
+
     apiUrl: function() {
       return this.doc.url();
     }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/a5b888bb/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js 
b/src/fauxton/app/modules/documents/views.js
index 6c92cfa..ab6b0e8 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -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;
     },
@@ -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);
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/a5b888bb/src/fauxton/app/templates/documents/doc_field_editor_tabs.html
----------------------------------------------------------------------
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 01cb8a9..fcc2b53 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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/a5b888bb/src/fauxton/app/templates/documents/duplicate_doc_modal.html
----------------------------------------------------------------------
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 0000000..dba8d44
--- /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>
+
+

Reply via email to