You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2014/10/29 09:56:36 UTC

fauxton commit: updated refs/heads/master to 0592645

Repository: couchdb-fauxton
Updated Branches:
  refs/heads/master 1fdc80785 -> 059264511


Add New Database now opens in tray, not prompt

- minor CSS update to all trays to increase edge padding

Closes COUCHDB-2398


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

Branch: refs/heads/master
Commit: 0592645117d0f26d803e05ed792a5464c048d2ea
Parents: 1fdc807
Author: Benjamin Keen <be...@gmail.com>
Authored: Wed Oct 22 16:25:49 2014 -0700
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Oct 29 10:56:15 2014 +0200

----------------------------------------------------------------------
 app/addons/databases/assets/less/databases.less |  35 ++-
 app/addons/databases/templates/newdatabase.html |  12 +-
 app/addons/databases/views.js                   | 289 +++++++++++--------
 .../documents/assets/less/queryOptions.less     |   1 +
 app/addons/fauxton/components.js                |  12 +-
 assets/less/fauxton.less                        |   2 +-
 6 files changed, 225 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/05926451/app/addons/databases/assets/less/databases.less
----------------------------------------------------------------------
diff --git a/app/addons/databases/assets/less/databases.less b/app/addons/databases/assets/less/databases.less
index 27784f9..fb220dd 100644
--- a/app/addons/databases/assets/less/databases.less
+++ b/app/addons/databases/assets/less/databases.less
@@ -33,10 +33,41 @@
   }
 }
 
-#new {
+#add-new-database {
   line-height: 40px;
 
-  a {
+  &:hover {
+    transition: none;
     text-decoration: none;
+    color: @red;
   }
 }
+
+.new-database-tray {
+  padding: 16px 20px 28px;
+  &:before {
+    right: 153px;
+  }
+
+  #new-database-name {
+    margin-bottom: 0px;
+    width: 250px;
+    .border-radius(5px 0 0 5px);
+  }
+
+  a.btn {
+    color: white;
+    background-color: #af2d24;
+    margin-left: -4px;
+    line-height: 1.5em;
+    border: 0px;
+    padding: 10px 10px 9px;
+    font-size: 14px;
+    .border-radius(0 5px 5px 0);
+
+    &:hover {
+      background-color: #cbcbcb;
+      color: white;
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/05926451/app/addons/databases/templates/newdatabase.html
----------------------------------------------------------------------
diff --git a/app/addons/databases/templates/newdatabase.html b/app/addons/databases/templates/newdatabase.html
index 2b25aac..f2220c5 100644
--- a/app/addons/databases/templates/newdatabase.html
+++ b/app/addons/databases/templates/newdatabase.html
@@ -1,4 +1,4 @@
-<!--
+<%/*
 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
@@ -10,7 +10,11 @@ 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.
--->
-
-<a id="new"><i class="icon fonticon-new-database"></i> Add New Database</a>
+*/%>
+<a id="add-new-database" class="add-new-database-btn" href="#"><i class="icon fonticon-new-database"></i> Add New Database</a>
 
+<div class="new-database-tray tray">
+  <span class="add-on">Add New Database</span>
+  <input id="new-database-name" type="text" class="input-xxlarge" placeholder="Name of database">
+  <a class="btn" id="js-create-database">Create</a>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/05926451/app/addons/databases/views.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/views.js b/app/addons/databases/views.js
index 3def8eb..09b3862 100644
--- a/app/addons/databases/views.js
+++ b/app/addons/databases/views.js
@@ -11,56 +11,66 @@
 // the License.
 
 define([
-  "app",
-
-  "addons/fauxton/components",
-  "api",
-  "addons/databases/resources"
+  'app',
+  'addons/fauxton/components',
+  'api',
+  'addons/databases/resources'
 ],
 
 function(app, Components, FauxtonAPI, Databases) {
+
   var Views = {};
 
   Views.RightAllDBsHeader = FauxtonAPI.View.extend({
-    className: "header-right",
-    template: "addons/databases/templates/header_alldbs",
+    className: 'header-right',
+    template: 'addons/databases/templates/header_alldbs',
 
-    beforeRender:function(){
-      this.headerSearch = this.insertView("#header-search", new Views.JumpToDB({
+    beforeRender: function () {
+      this.headerSearch = this.insertView('#header-search', new JumpToDBView({
         collection: this.collection
       }));
 
-      this.newbutton = this.insertView("#add-db-button", new Views.NewDatabaseButton({
+      this.newbutton = this.insertView('#add-db-button', new NewDatabaseView({
         collection: this.collection
       }));
     }
   });
 
   Views.Item = FauxtonAPI.View.extend({
-    template: "addons/databases/templates/item",
-    tagName: "tr",
-    establish: function(){
+    template: 'addons/databases/templates/item',
+    tagName: 'tr',
+
+    establish: function () {
       return [this.model.fetch()];
     },
-    serialize: function() {
 
+    serialize: function () {
       return {
-        encoded: app.utils.safeURLName(this.model.get("name")),
+        encoded: app.utils.safeURLName(this.model.get('name')),
         database: this.model
       };
     }
   });
 
-  Views.JumpToDB = FauxtonAPI.View.extend({
-    template: "addons/databases/templates/jump_to_db",
+  Views.List = FauxtonAPI.View.extend({
+    dbLimit: 20,
+    perPage: 20,
+    template: 'addons/databases/templates/list',
     events: {
-      "submit form#jump-to-db": "switchDatabase"
+      'click button.all': 'selectAll'
     },
-    initialize: function(options) {
+
+    initialize: function (options) {
       var params = app.getParams();
       this.page = params.page ? parseInt(params.page, 10) : 1;
     },
-    establish: function(){
+
+    serialize: function () {
+      return {
+        databases: this.collection
+      };
+    },
+    establish: function () {
       var currentDBs = this.paginated();
       var deferred = FauxtonAPI.Deferred();
 
@@ -73,20 +83,80 @@ function(app, Components, FauxtonAPI, Databases) {
       });
       return [deferred];
     },
-    switchDatabase: function(event, selectedName) {
+
+    paginated: function () {
+      var start = (this.page - 1) * this.perPage;
+      var end = this.page * this.perPage;
+      return this.collection.slice(start, end);
+    },
+
+    beforeRender: function () {
+      _.each(this.paginated(), function(database) {
+        this.insertView('table.databases tbody', new Views.Item({
+          model: database
+        }));
+      }, this);
+
+      this.insertView('#database-pagination', new Components.Pagination({
+        page: this.page,
+        perPage: this.perPage,
+        total: this.collection.length,
+        urlFun: function (page) {
+          return '#/_all_dbs?page=' + page;
+        }
+      }));
+    },
+
+    setPage: function (page) {
+      this.page = page || 1;
+    },
+
+    selectAll: function (event) {
+      $('input:checkbox').attr('checked', !$(event.target).hasClass('active'));
+    }
+  });
+
+
+  // private Views
+
+  var JumpToDBView = FauxtonAPI.View.extend({
+    template: 'addons/databases/templates/jump_to_db',
+    events: {
+      'submit form#jump-to-db': 'switchDatabase'
+    },
+
+    initialize: function () {
+      var params = app.getParams();
+      this.page = params.page ? parseInt(params.page, 10) : 1;
+    },
+
+    establish: function () {
+      var currentDBs = this.paginated();
+      var deferred = FauxtonAPI.Deferred();
+
+      FauxtonAPI.when(currentDBs.map(function (database) {
+        return database.status.fetchOnce();
+      })).always(function (resp) {
+        // make this always so that even if a user is not allowed access to a database
+        // they will still see a list of all databases
+        deferred.resolve();
+      });
+      return [deferred];
+    },
+
+    switchDatabase: function (event, selectedName) {
       event && event.preventDefault();
 
-      var dbname = this.$el.find("[name='search-query']").val().trim();
+      var dbname = this.$el.find('[name="search-query"]').val().trim();
 
       if (selectedName) {
         dbname = selectedName;
       }
-
-      if (dbname && this.collection.where({"id":app.utils.safeURLName(dbname)}).length > 0){
+      if (dbname && this.collection.where({ id: app.utils.safeURLName(dbname) }).length > 0) {
           // TODO: switch to using a model, or Databases.databaseUrl()
           // Neither of which are in scope right now
           // var db = new Database.Model({id: dbname});
-          var url = ["/database/", app.utils.safeURLName(dbname), "/_all_docs"].join('');
+          var url = ['/database/', app.utils.safeURLName(dbname), '/_all_docs'].join('');
           FauxtonAPI.navigate(url);
       } else {
         FauxtonAPI.addNotification({
@@ -95,131 +165,122 @@ function(app, Components, FauxtonAPI, Databases) {
         });
       }
     },
-    afterRender: function() {
+
+    afterRender: function () {
       var that = this,
-          AllDBsArray = _.map(this.collection.toJSON(), function(item, key){
+          AllDBsArray = _.map(this.collection.toJSON(), function (item, key) {
             return item.name;
           });
 
       this.dbSearchTypeahead = new Components.Typeahead({
-        el: "input.search-autocomplete",
+        el: 'input.search-autocomplete',
         source: AllDBsArray,
         onUpdate: function (item) {
           that.switchDatabase(null, item);
         }
       });
       this.dbSearchTypeahead.render();
-      this.$el.find(".js-db-graveyard").tooltip();
+      this.$el.find('.js-db-graveyard').tooltip();
     }
   });
 
-  Views.List = FauxtonAPI.View.extend({
-    dbLimit: 20,
-    perPage: 20,
-    template: "addons/databases/templates/list",
+  var NewDatabaseView = FauxtonAPI.View.extend({
+    template: 'addons/databases/templates/newdatabase',
     events: {
-      "click button.all": "selectAll"
+      'click #add-new-database': 'toggleTray',
+      'click #js-create-database': 'createDatabase'
     },
 
-    initialize: function(options) {
-      var params = app.getParams();
-      this.page = params.page ? parseInt(params.page, 10) : 1;
-    },
+    initialize: function () {
+      var hideTray = _.bind(this.hideTray, this),
+        trayVisible = _.bind(this.trayVisible, this);
 
-    serialize: function() {
-      return {
-        databases: this.collection
-      };
-    },
-    establish: function(){
-      var currentDBs = this.paginated();
-      var deferred = FauxtonAPI.Deferred();
+      $('body').on('click.add-new-database', function(e) {
+        var $clickEl = $(e.target);
 
-      FauxtonAPI.when(currentDBs.map(function(database) {
-        return database.status.fetchOnce();
-      })).always(function(resp) {
-        //make this always so that even if a user is not allowed access to a database
-        //they will still see a list of all databases
-        deferred.resolve();
+        if (!trayVisible()) { return; }
+        if ($clickEl.closest('.add-new-database-btn').length) { return; }
+
+        if (!$clickEl.closest('.new-database-tray').length) {
+          hideTray();
+        }
       });
-      return [deferred];
     },
 
-    paginated: function() {
-      var start = (this.page - 1) * this.perPage;
-      var end = this.page * this.perPage;
-      return this.collection.slice(start, end);
+    cleanup: function() {
+      $('body').off('click.add-new-database');
     },
 
-    beforeRender: function() {
+    toggleTray: function (e) {
+      e.preventDefault();
 
-      _.each(this.paginated(), function(database) {
-        this.insertView("table.databases tbody", new Views.Item({
-          model: database
-        }));
-      }, this);
+      // curious. If we don't prevent bubbling, the parent View is redrawn (?)
+      e.stopImmediatePropagation();
 
-      this.insertView("#database-pagination", new Components.Pagination({
-        page: this.page,
-        perPage: this.perPage,
-        total: this.collection.length,
-        urlFun: function(page) {
-          return "#/_all_dbs?page=" + page;
-        }
-      }));
+      if (this.trayVisible()) {
+        this.hideTray();
+      } else {
+        this.showTray();
+      }
     },
 
-    setPage: function(page) {
-      this.page = page || 1;
+    hideTray: function () {
+      var $tray = this.$('.tray');
+      $tray.velocity('reverse', 250, function () {
+        $tray.hide();
+      });
+      this.$('#add-new-database').removeClass('enabled');
     },
-    selectAll: function(evt){
-      $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
-    }
-  });
 
+    showTray: function () {
+      // boo! to be refactored out later (see COUCHDB-2401)
+      FauxtonAPI.Events.trigger("APIbar:closeTray");
 
-  Views.NewDatabaseButton = FauxtonAPI.View.extend({
-    template: "addons/databases/templates/newdatabase",
-    events: {
-      "click a#new": "newDatabase"
-    },
-    newDatabase: function() {
-      var notification;
-      var db;
-      // TODO: use a modal here instead of the prompt
-      var name = prompt('Name of database', 'newdatabase');
-      if (name === null) {
-        return;
-      } else if (name.length === 0) {
-        notification = FauxtonAPI.addNotification({
-          msg: "Please enter a valid database name",
-          type: "error",
+      this.$('.tray').velocity('transition.slideDownIn', 250);
+      this.$('#add-new-database').addClass('enabled');
+    },
+
+    trayVisible: function () {
+      return this.$('.tray').is(':visible');
+    },
+
+    createDatabase: function (e) {
+      e.preventDefault();
+
+      var databaseName = $.trim(this.$('#new-database-name').val());
+      if (databaseName.length === 0) {
+        FauxtonAPI.addNotification({
+          msg: 'Please enter a valid database name',
+          type: 'error',
           clear: true
         });
         return;
       }
-      db = new this.collection.model({
-        id: name,
-        name: name
+      this.hideTray();
+
+      var db = new this.collection.model({
+        id: databaseName,
+        name: databaseName
       });
-      notification = FauxtonAPI.addNotification({msg: "Creating database."});
-      db.save().done(function() {
-        notification = FauxtonAPI.addNotification({
-          msg: "Database created successfully",
-          type: "success",
-          clear: true
-        });
-        var route = "#/database/" +  app.utils.safeURLName(name) + "/_all_docs?limit=" + Databases.DocLimit;
-        app.router.navigate(route, { trigger: true });
-      }
-      ).error(function(xhr) {
-        var responseText = JSON.parse(xhr.responseText).reason;
-        notification = FauxtonAPI.addNotification({
-          msg: "Create database failed: " + responseText,
-          type: "error",
-          clear: true
-        });
-      }
+      FauxtonAPI.addNotification({ msg: 'Creating database.' });
+
+      db.save().done(function () {
+          FauxtonAPI.addNotification({
+            msg: 'Database created successfully',
+            type: 'success',
+            clear: true
+          });
+          var route = '#/database/' + app.utils.safeURLName(databaseName) + '/_all_docs?limit=' + Databases.DocLimit;
+          app.router.navigate(route, { trigger: true });
+        }
+      ).error(function (xhr) {
+          var responseText = JSON.parse(xhr.responseText).reason;
+          FauxtonAPI.addNotification({
+            msg: 'Create database failed: ' + responseText,
+            type: 'error',
+            clear: true
+          });
+        }
       );
     }
   });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/05926451/app/addons/documents/assets/less/queryOptions.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/queryOptions.less b/app/addons/documents/assets/less/queryOptions.less
index 51bb4ac..ed852de 100644
--- a/app/addons/documents/assets/less/queryOptions.less
+++ b/app/addons/documents/assets/less/queryOptions.less
@@ -16,6 +16,7 @@
 
 #query-options-tray {
   width: 490px;
+  padding-top: 6px;
 
   .query-group:first-child {
     margin-top: 0px;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/05926451/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/components.js b/app/addons/fauxton/components.js
index 490ae95..cf80d9a 100644
--- a/app/addons/fauxton/components.js
+++ b/app/addons/fauxton/components.js
@@ -114,15 +114,18 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
       var hideAPIbar = _.bind(this.hideAPIbar, this),
           navbarVisible = _.bind(this.navbarVisible, this);
 
-      $('body').on('click.apibar',function(e) {
+      $('body').on('click.apibar', function(e) {
         var $navbar = $(e.target);
+
         if (!navbarVisible()) { return;}
         if ($navbar.hasClass('.api-url-btn')) { return; }
 
-        if (!$navbar.closest('.api-navbar').length){
+        if (!$navbar.closest('#api-navbar').length){
           hideAPIbar();
         }
       });
+
+      FauxtonAPI.Events.on('APIbar:closeTray', this.hideAPIbar, this);
     },
 
     navbarVisible: function () {
@@ -130,9 +133,8 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
     },
 
     cleanup: function () {
-      // a bit of a hack. The api bar is created twice so we cannot stop listening
-      // to this event until we refactor the api bars into one
-      //$('body').off('click.apibar');
+      $('body').off('click.apibar');
+      FauxtonAPI.Events.off('APIbar:closeTray');
     },
 
     hideAPIbar: function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/05926451/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/assets/less/fauxton.less b/assets/less/fauxton.less
index 9341b02..ff22dc6 100644
--- a/assets/less/fauxton.less
+++ b/assets/less/fauxton.less
@@ -362,7 +362,7 @@ header .header-icon {
   background: none;
 }
 .api-navbar {
-  padding: 5px 20px;
+  padding: 16px 20px;
   .input-append.input-prepend {
     margin-bottom: 0px;
     .copying {