Эх сурвалжийг харах

HUE-1655 [hbase] Modified the modal to allow multiple properties per each column

Enrico Berti 11 жил өмнө
parent
commit
62ee84f01a

+ 10 - 1
apps/hbase/src/hbase/api.py

@@ -41,6 +41,7 @@ class HbaseApi(object):
   def query(self, action, *args):
     try:
       if hasattr(self, action):
+        print args
         return getattr(self, action)(*args)
       cluster = args[0]
       return self.queryCluster(action, cluster, *args[1:])
@@ -117,8 +118,16 @@ class HbaseApi(object):
     return client.getVerTs(tableName, smart_str(row), smart_str(column), timestamp, numVersions, attributesargs)
 
   def createTable(self, cluster, tableName, *columns):
+    print cluster
+    print tableName
+    print columns, ' ---'
+    
+    # ([{u'name': u'ff', u'properties': [{}]}, {u'properties': []}, {u'name': u'fffff', u'properties': [{}]}, {u'properties': []}],)  ---
+    # -->
+    # ([{u'name': u'ff', u'properties': [{}]}, {u'name': u'fffff', u'properties': [{}]},)  ---
+    
     client = self.connectCluster(cluster)
-    client.createTable(tableName, [get_thrift_type('ColumnDescriptor')(name=column) for column in columns])
+    client.createTable(tableName, [get_thrift_type('ColumnDescriptor')(name=column['name']) for column in columns])
     return "%s successfully created" % tableName
 
   def getTableList(self, cluster):

+ 41 - 27
apps/hbase/src/hbase/templates/app.mako

@@ -175,7 +175,7 @@ ${ commonheader(None, "hbase", user) | n,unicode }
         % endif
         % if can_write:
         <span class="pull-right">
-          <a href="#new_table_modal" role="button" data-bind="click: function(){app.focusModel(app.views.tables);}" class="btn" data-toggle="modal"><i class='fa fa-plus-circle'></i> ${_('New Table')}</a>
+          <a href="#new_table_modal" role="button" data-bind="click: function(){prepareNewTableForm(); app.focusModel(app.views.tables);}" class="btn" data-toggle="modal"><i class='fa fa-plus-circle'></i> ${_('New Table')}</a>
         </span>
         % endif
       </div>
@@ -194,37 +194,51 @@ ${ commonheader(None, "hbase", user) | n,unicode }
     <!-- New Table Modal -->
     <form id="new_table_modal" action="createTable" method="POST" class="modal hide fade ajaxSubmit" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
       <div class="modal-header">
-        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <a class="close pointer" data-dismiss="modal" aria-hidden="true">&times;</a>
         <h3>${_('Create New Table')}</h3>
       </div>
       <div class="modal-body controls">
         <input type="hidden" name="cluster" data-bind="value:app.cluster"/>
         <label>${_('Table Name')}:</label> <input name="tableName" placeholder="MyTable" type="text"/>
         <label>${_('Column Families')}:</label>
-        <ul>
-          <li>
-            <input type="text" name="table_columns" placeholder="family_name">
-            <select name="table_columns_propery" style="width:100px">
-			    <option data-default="3" selected>maxVersions</option>
-			    <option data-default="NONE">compression</option>
-			    <option data-default="true">inMemory</option>
-			    <option data-default="NONE">bloomFilterType</option>
-			    <option data-default="0">bloomFilterVectorSize</option>
-			    <option data-default="0">bloomFilterNbHashes</option>
-			    <option data-default="true">blockCacheEnabled</option>
-			    <option data-default="-1">timeToLive</option>
-			 </select>
-			  <input type="text" name="table_columns" placeholder="3" style="width:50px">
-			  <i class="fa fa-plus-circle"></i>
-          </li>
-        </ul>
-        <a class="btn action_addColumn"><i class="fa fa-plus-circle"></i> ${_('Additional Column Family')}</a>
+        <ul class="columns"></ul>
+        <a class="pointer action_addColumn"><i class="fa fa-plus-circle"></i> ${_('Add an additional column family')}</a>
       </div>
       <div class="modal-footer">
         <button class="btn" data-dismiss="modal" aria-hidden="true">${_('Cancel')}</button>
         <input type="submit" class="btn btn-primary" value="${_('Submit')}"/>
       </div>
     </form>
+
+    <script id="columnTemplate" type="text/html">
+      <ul class="pull-right columnProperties"></ul>
+      <div class="inline" style="width: 24px">
+        <a class="pointer action_removeColumn" title="${_('Remove Column Family')}"><i class="fa fa-times"></i></a>
+      </div>
+      <input type="text" name="table_columns" placeholder="family_name" class="no-margin">
+      <div class="clearfix"></div>
+    </script>
+
+    <script id="columnPropertyTemplate" type="text/html">
+      <select name="table_columns_property" style="width:180px" class="no-margin">
+        <option data-default="3" selected>maxVersions</option>
+        <option data-default="NONE">compression</option>
+        <option data-default="true">inMemory</option>
+        <option data-default="NONE">bloomFilterType</option>
+        <option data-default="0">bloomFilterVectorSize</option>
+        <option data-default="0">bloomFilterNbHashes</option>
+        <option data-default="true">blockCacheEnabled</option>
+        <option data-default="-1">timeToLive</option>
+      </select>
+      <input type="text" name="table_columns_property_value" placeholder="3" style="width:80px" class="no-margin">
+      <a class="pointer action_removeColumnProperty" title="${_('Remove column property')}"><i class="fa fa-minus-circle"></i></a>
+      <a class="pointer action_addColumnProperty" title="${_('Additional column property')}"><i class="fa fa-plus-circle"></i></a>
+    </script>
+    <script id="columnPropertyEmptyTemplate" type="text/html">
+      <li class="columnPropertyEmpty" style="width:310px; line-height: 29px">
+        <a class="pointer action_addColumnProperty"><i class="fa fa-plus-circle"></i> ${_('Add a column property')}</a>
+      </li>
+    </script>
   </div>
 
   <!-- Table View Page -->
@@ -309,7 +323,7 @@ ${ commonheader(None, "hbase", user) | n,unicode }
     </form>
     <script id="new_row_modal_template" type="text/html">
       <div class="modal-header">
-        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <a class="close pointer" data-dismiss="modal" aria-hidden="true">&times;</a>
         <h3>${_('Insert New Row')}</h3>
       </div>
       <div class="modal-body controls">
@@ -332,7 +346,7 @@ ${ commonheader(None, "hbase", user) | n,unicode }
     </form>
     <script id="new_column_modal_template" type="text/html">
       <div class="modal-header">
-          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+          <a class="close pointer" data-dismiss="modal" aria-hidden="true">&times;</a>
           <h3>${_('Create New Column')}</h3>
         </div>
         <div class="modal-body controls">
@@ -357,8 +371,8 @@ ${ commonheader(None, "hbase", user) | n,unicode }
 
     <script id="cell_edit_modal_template" type="text/html">
       <div class="modal-header">
-        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-        <h3>${_('Edit Cell')} - <span data-bind="text: content.name || formatTimestamp(content.timestamp)"></span> <code data-bind="text: mime"></code> <small><i class="fa fa-clock-o"></i> <span data-bind="text: $data.content.timestamp"></span></small></h3>
+        <a class="close pointer" data-dismiss="modal" aria-hidden="true">&times;</a>
+        <h3>${_('Edit Cell')} - <span data-bind="text: content.name || formatTimestamp(content.timestamp)"></span> <code data-bind="text: mime"></code> <small><i class="fa fa-clock-o"></i> <span data-bind="text: formatTimestamp($data.content.timestamp)"></span></small></h3>
       </div>
       <div class="modal-body container-fluid">
           <div class="row-fluid">
@@ -373,10 +387,10 @@ ${ commonheader(None, "hbase", user) | n,unicode }
               <!-- /ko -->
             </div>
             <div class="span3">
-              <ul class="nav nav-list">
+              <ul class="nav nav-list cell-history">
                 <li class="nav-header">${_('Cell History:')}</li>
                 <!-- ko foreach: $data.content.history.items() -->
-                  <li data-bind="css: { 'active': $data.timestamp == $parent.content.timestamp }"><a data-bind="click: $parent.content.history.pickHistory.bind(null, $data), text: formatTimestamp($data.timestamp)"></a></li>
+                  <li data-bind="css: { 'active': $data.timestamp == $parent.content.timestamp }"><a data-bind="click: $parent.content.history.pickHistory.bind(null, $data), text: formatTimestamp($data.timestamp)" class="pointer"></a></li>
                 <!-- /ko -->
                 <li data-bind="visible: $data.content.history.loading()"><img src="/static/art/spinner.gif" /></li>
               </ul>
@@ -412,7 +426,7 @@ ${ commonheader(None, "hbase", user) | n,unicode }
   <div id="confirm-modal" action="createTable" method="POST" class="modal hide fade"></div>
   <script id="confirm_template" type="text/html">
     <div class="modal-header">
-      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+      <a class="close pointer" data-dismiss="modal" aria-hidden="true">&times;</a>
       <h3 data-bind="text: title"></h3>
     </div>
     <div class="modal-body" data-bind="text: text">

+ 11 - 0
apps/hbase/static/css/hbase.css

@@ -538,6 +538,7 @@ ul#hbase-breadcrumbs li a {
 }
 
 #cell_edit_modal .modal-body {
+  min-height: 400px;
   max-height: 600px;
 }
 
@@ -616,3 +617,13 @@ textarea {
   border-color: #333;
   box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
 }
+
+.cell-history {
+  border: none;
+  border-left: 1px solid #d5d5d5;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+  min-height: 400px;
+  background-color: #FFFFFF;
+}

+ 102 - 37
apps/hbase/static/js/app.js

@@ -194,46 +194,72 @@ function bindSubmit() {
   var self = this;
   var data = [];
   var hash_cache = {};
-  $(this).find('.controls > input, .controls > textarea, .controls > ul input').not('input[type=submit]').each(function() {
-    if($(this).hasClass('ignore'))
-      return;
-    var use_post = $(this).data('use-post');
-    var submitVal = null;
-    if($(this).data('subscribe')) {
-      var target = $($(this).data('subscribe'));
-      switch(target[0].tagName) {
-        case "UL":
-          var serialized = {};
-          target.find('li').each(function() {
-            serialized[$(this).find('input')[0].value] = $(this).find('input')[1].value;
-          });
-          submitVal = serialized;
-          use_post = true;
-          break;
+  if ($(this).attr("id") == "new_table_modal"){
+    var _cols = [];
+    $(this).find(".columns li").each(function(cnt, column){
+      var _props = [];
+      $(column).find(".columnProperties li").each(function(icnt, property){
+        _props.push({
+          name: $(property).find("select").val(),
+          value: $(property).find("input[name='table_columns_property_value']").val()
+        });
+      });
+      _cols.push({
+        name: $(column).find("input[name='table_columns']").val(),
+        properties: _props
+      });
+    });
+    data = [
+      $(this).find("input[name='cluster']").val(),
+      $(this).find("input[name='tableName']").val(),
+      JSON.stringify(_cols)
+    ]
+  }
+  else {
+    $(this).find('.controls > input, .controls > textarea, .controls > ul input').not('input[type=submit]').each(function() {
+      if($(this).hasClass('ignore'))
+        return;
+      var use_post = $(this).data('use-post');
+      var submitVal = null;
+      if($(this).data('subscribe')) {
+        var target = $($(this).data('subscribe'));
+        switch(target[0].tagName) {
+          case "UL":
+            var serialized = {};
+            target.find('li').each(function() {
+              serialized[$(this).find('input')[0].value] = $(this).find('input')[1].value;
+            });
+            submitVal = serialized;
+            use_post = true;
+            break;
+        }
       }
-    }
-    else if($(this).hasClass('serializeHash')) {
-      var target = $(this).attr('name');
-      if(!hash_cache[target])
-        hash_cache[target] = {};
-      hash_cache[target][$(this).data(key)] = $(this).val();
-    }
-    else {
-      submitVal = $(this).val();
-      //change reload next
-    }
-    if(submitVal) {
-      if(use_post)
-        submitVal = "hbase-post-key-" + JSON.stringify(submitVal);
-      else
-        submitVal = prepForTransport(submitVal);
-      data.push(submitVal);
-    }
-  });
+      else if($(this).hasClass('serializeHash')) {
+        var target = $(this).attr('name');
+        if(!hash_cache[target])
+          hash_cache[target] = {};
+        hash_cache[target][$(this).data(key)] = $(this).val();
+      }
+      else {
+        submitVal = $(this).val();
+        //change reload next
+      }
+      if(submitVal) {
+        if(use_post) {
+          submitVal = "hbase-post-key-" + JSON.stringify(submitVal);
+        } else {
+          submitVal = prepForTransport(submitVal);
+        }
+        data.push(submitVal);
+      }
+    });
+  }
+
   $(this).find('input[type=submit]').addClass('disabled').showIndicator();
   var ui = app.focusModel();
   if(ui)
     ui.isLoading(true);
+
   API.queryArray($(this).attr('action'), data).complete(function() {
     $(self).find('input[type=submit]').removeClass('disabled').hideIndicator();
     if(ui)
@@ -243,12 +269,51 @@ function bindSubmit() {
     if(ui)
       app.focusModel().reload();
   });
+
   return false;
 }
 $('form.ajaxSubmit').submit(bindSubmit).on('hidden', function() {
   $(this).trigger('reset');
 });
 
-$('a.action_addColumn').click(function() {
-  $(this).parent().find("ul").append("<li><input type=\"text\" name=\"table_columns\" placeholder = \"family_name\"/></li>")
+var prepareNewTableForm = function () {
+  $("#new_table_modal .modal-body ul").empty();
+  addColumnToNewTableForm();
+}
+
+var addColumnToNewTableForm = function() {
+  var $li = $("<li>").addClass("column").css("marginBottom", "10px").html($("#columnTemplate").html());
+  addColumnPropertyToColumn($li);
+  $li.appendTo($("#new_table_modal .modal-body ul.columns"));
+}
+
+var addColumnPropertyToColumn = function (col){
+  var $li = $("<li>").addClass("columnProperty").css("marginBottom", "5px").html($("#columnPropertyTemplate").html());
+  $li.find("select").on("change", function(){
+    $li.find("[name='table_columns_property_value']").attr("placeholder", $(this).find("option:selected").data("default"));
+  });
+  $li.appendTo(col.find("ul"));
+}
+
+$(document).on("click", "a.action_addColumn", function() {
+  addColumnToNewTableForm();
+});
+
+
+$(document).on("click", "a.action_removeColumn", function() {
+  $(this).parents("li").remove();
+});
+
+$(document).on("click", "a.action_addColumnProperty", function() {
+  addColumnPropertyToColumn($(this).parents(".column"));
+  $(this).parents(".column").find(".columnPropertyEmpty").remove();
+});
+
+$(document).on("click", "a.action_removeColumnProperty", function() {
+  var _col = $(this).parents(".column");
+  _col.find(".columnPropertyEmpty").remove();
+  $(this).parent().remove();
+  if (_col.find("li").length == 0){
+    _col.find("ul").html($("#columnPropertyEmptyTemplate").html());
+  }
 });

+ 1 - 2
desktop/core/static/css/hue3.css

@@ -1743,10 +1743,9 @@ border-bottom-left-radius: 0px;
   font-size: 1.5em;
 }
 
-input.no-margin {
+input.no-margin, select.no-margin {
   margin-bottom: 0;
 }
-
 /****************************************************
  *
  * Styles for opaque layover messages