Преглед изворни кода

HUE-1660 [core] Prettify import dialog on Spark notebooks

Enrico Berti пре 10 година
родитељ
комит
bcb2e76

+ 28 - 9
apps/spark/src/spark/templates/notebooks.mako

@@ -50,7 +50,7 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
         </a>
 
         <a data-bind="click: function() { atLeastOneSelected() ? exportDocuments() : void(0) }, css: {'btn': true, 'disabled': ! atLeastOneSelected() }">
-          <i class="fa fa-upload"></i> ${ _('Export') }
+          <i class="fa fa-download"></i> ${ _('Export') }
         </a>
       </div>
     </%def>
@@ -58,7 +58,7 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
     <%def name="creation()">
       <a href="${ url('spark:new') }" class="btn"><i class="fa fa-plus-circle"></i> ${ _('Create') }</a>
       <a data-bind="click: function() { $('#import-documents').modal('show'); }" class="btn">
-        <i class="fa fa-download"></i> ${ _('Import') }
+        <i class="fa fa-upload"></i> ${ _('Import') }
       </a>
     </%def>
   </%actionbar:render>
@@ -124,18 +124,34 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
   </form>
 </div>
 
-<div id="import-documents" class="modal hide fade">
+<div id="import-documents" class="modal hide fade fileupload-modal">
+  <div class="modal-header">
+    <a href="#" class="close" data-dismiss="modal" data-clear="fileupload">&times;</a>
+    <h3>${_('Import documents')}</h3>
+  </div>
   <form method="POST" action="/desktop/api2/doc/import" style="display: inline" enctype="multipart/form-data">
-    ${ csrf_token(request) | n,unicode }
-    <input type="file" name="documents" accept="application/json"/>
-    <input type="hidden" name="redirect" value="${ request.get_full_path() }"/>
-    </br>
-    <a href="#" class="btn" data-dismiss="modal">${ _('Cancel') }</a>
-    <input type="submit" class="btn btn-danger" value="${ _('Import') }"/>
+    <div class="modal-body form-inline">
+      <div class="pull-right">
+        <a href="#" class="btn" data-dismiss="modal" data-clear="fileupload">${ _('Cancel') }</a>
+        <input type="submit" class="btn btn-danger" value="${ _('Import') }"/>
+      </div>
+      <div class="fileupload fileupload-new" data-provides="fileupload">
+        <span class="btn btn-file" style="line-height: 29px">
+          <span class="fileupload-new">${ _('Select file') }</span>
+          <span class="fileupload-exists">${ _('Change') }</span>
+          <input type="file" name="documents" accept="application/json" />
+        </span>
+        &nbsp;&nbsp;<span class="fileupload-preview"></span>
+          <a href="#" class="fileupload-exists" data-clear="fileupload"><i class="fa fa-times"></i></a>
+      </div>
+      ${ csrf_token(request) | n,unicode }
+      <input type="hidden" name="redirect" value="${ request.get_full_path() }"/>
+    </div>
   </form>
 </div>
 
 
+
 </div>
 
 
@@ -147,6 +163,9 @@ ${ commonshare() | n,unicode }
 <script src="${ static('desktop/ext/js/knockout.mapping-2.3.2.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/js/share.vm.js') }"></script>
 
+<script src="${ static('desktop/ext/js/bootstrap-fileupload.js') }" type="text/javascript" charset="utf-8"></script>
+<link rel="stylesheet" href="${ static('desktop/ext/css/bootstrap-fileupload.css') }">
+
 
 <script type="text/javascript" charset="utf-8">
   var Editor = function () {

+ 2 - 0
desktop/core/src/desktop/static/desktop/ext/css/bootstrap-fileupload.css

@@ -0,0 +1,2 @@
+/* CSS crunched with Crunch - http://crunchapp.net/ */
+.btn-file{overflow:hidden;position:relative;vertical-align:middle}.btn-file>input{position:absolute;top:0;right:0;margin:0;opacity:0;filter:alpha(opacity=0);transform:translate(-300px, 0) scale(4);font-size:23px;direction:ltr;cursor:pointer}.fileupload{margin-bottom:9px}.fileupload .uneditable-input{display:inline-block;margin-bottom:0px;vertical-align:middle;cursor:text}.fileupload .thumbnail{overflow:hidden;display:inline-block;margin-bottom:5px;vertical-align:middle;text-align:center}.fileupload .thumbnail>img{display:inline-block;vertical-align:middle;max-height:100%}.fileupload .btn{vertical-align:middle}.fileupload-exists .fileupload-new,.fileupload-new .fileupload-exists{display:none}.fileupload-inline .fileupload-controls{display:inline}.fileupload-new .input-append .btn-file{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.thumbnail-borderless .thumbnail{border:none;padding:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.fileupload-new.thumbnail-borderless .thumbnail{border:1px solid #ddd}.control-group.warning .fileupload .uneditable-input{color:#a47e3c;border-color:#a47e3c}.control-group.warning .fileupload .fileupload-preview{color:#a47e3c}.control-group.warning .fileupload .thumbnail{border-color:#a47e3c}.control-group.error .fileupload .uneditable-input{color:#b94a48;border-color:#b94a48}.control-group.error .fileupload .fileupload-preview{color:#b94a48}.control-group.error .fileupload .thumbnail{border-color:#b94a48}.control-group.success .fileupload .uneditable-input{color:#468847;border-color:#468847}.control-group.success .fileupload .fileupload-preview{color:#468847}.control-group.success .fileupload .thumbnail{border-color:#468847}

+ 169 - 0
desktop/core/src/desktop/static/desktop/ext/js/bootstrap-fileupload.js

@@ -0,0 +1,169 @@
+/* ===========================================================
+ * bootstrap-fileupload.js j2
+ * http://jasny.github.com/bootstrap/javascript.html#fileupload
+ * ===========================================================
+ * Copyright 2012 Jasny BV, Netherlands.
+ *
+ * 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.
+ * ========================================================== */
+
+!function ($) {
+
+  "use strict"; // jshint ;_
+
+ /* FILEUPLOAD PUBLIC CLASS DEFINITION
+  * ================================= */
+
+  var Fileupload = function (element, options) {
+    this.$element = $(element)
+    this.type = this.$element.data('uploadtype') || (this.$element.find('.thumbnail').length > 0 ? "image" : "file")
+      
+    this.$input = this.$element.find(':file')
+    if (this.$input.length === 0) return
+
+    this.name = this.$input.attr('name') || options.name
+
+    this.$hidden = this.$element.find('input[type=hidden][name="'+this.name+'"]')
+    if (this.$hidden.length === 0) {
+      this.$hidden = $('<input type="hidden" />')
+      this.$element.prepend(this.$hidden)
+    }
+
+    this.$preview = this.$element.find('.fileupload-preview')
+    var height = this.$preview.css('height')
+    if (this.$preview.css('display') != 'inline' && height != '0px' && height != 'none') this.$preview.css('line-height', height)
+
+    this.original = {
+      'exists': this.$element.hasClass('fileupload-exists'),
+      'preview': this.$preview.html(),
+      'hiddenVal': this.$hidden.val()
+    }
+    
+    this.$remove = this.$element.parents('.fileupload-modal').find('[data-clear="fileupload"]')
+
+    this.$element.find('[data-trigger="fileupload"]').on('click.fileupload', $.proxy(this.trigger, this))
+
+    this.listen()
+  }
+  
+  Fileupload.prototype = {
+    
+    listen: function() {
+      this.$input.on('change.fileupload', $.proxy(this.change, this))
+      $(this.$input[0].form).on('reset.fileupload', $.proxy(this.reset, this))
+      if (this.$remove) this.$remove.on('click.fileupload', $.proxy(this.clear, this))
+    },
+    
+    change: function(e, invoked) {
+      if (invoked === 'clear') return
+      
+      var file = e.target.files !== undefined ? e.target.files[0] : (e.target.value ? { name: e.target.value.replace(/^.+\\/, '') } : null)
+      
+      if (!file) {
+        this.clear()
+        return
+      }
+      
+      this.$hidden.val('')
+      this.$hidden.attr('name', '')
+      this.$input.attr('name', this.name)
+
+      if (this.type === "image" && this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
+        var reader = new FileReader()
+        var preview = this.$preview
+        var element = this.$element
+
+        reader.onload = function(e) {
+          preview.html('<img src="' + e.target.result + '" ' + (preview.css('max-height') != 'none' ? 'style="max-height: ' + preview.css('max-height') + ';"' : '') + ' />')
+          element.addClass('fileupload-exists').removeClass('fileupload-new')
+        }
+
+        reader.readAsDataURL(file)
+      } else {
+        this.$preview.text(file.name)
+        this.$element.addClass('fileupload-exists').removeClass('fileupload-new')
+      }
+    },
+
+    clear: function(e) {
+      this.$hidden.val('')
+      this.$hidden.attr('name', this.name)
+      this.$input.attr('name', '')
+
+      //ie8+ doesn't support changing the value of input with type=file so clone instead
+      if (navigator.userAgent.match(/msie/i)){ 
+          var inputClone = this.$input.clone(true);
+          this.$input.after(inputClone);
+          this.$input.remove();
+          this.$input = inputClone;
+      }else{
+          this.$input.val('')
+      }
+
+      this.$preview.html('')
+      this.$element.addClass('fileupload-new').removeClass('fileupload-exists')
+
+      if (e) {
+        this.$input.trigger('change', [ 'clear' ])
+        e.preventDefault()
+      }
+    },
+    
+    reset: function(e) {
+      this.clear()
+      
+      this.$hidden.val(this.original.hiddenVal)
+      this.$preview.html(this.original.preview)
+      
+      if (this.original.exists) this.$element.addClass('fileupload-exists').removeClass('fileupload-new')
+       else this.$element.addClass('fileupload-new').removeClass('fileupload-exists')
+    },
+    
+    trigger: function(e) {
+      this.$input.trigger('click')
+      e.preventDefault()
+    }
+  }
+
+  
+ /* FILEUPLOAD PLUGIN DEFINITION
+  * =========================== */
+
+  $.fn.fileupload = function (options) {
+    return this.each(function () {
+      var $this = $(this)
+      , data = $this.data('fileupload')
+      if (!data) $this.data('fileupload', (data = new Fileupload(this, options)))
+      if (typeof options == 'string') data[options]()
+    })
+  }
+
+  $.fn.fileupload.Constructor = Fileupload
+
+
+ /* FILEUPLOAD DATA-API
+  * ================== */
+
+  $(document).on('click.fileupload.data-api', '[data-provides="fileupload"]', function (e) {
+    var $this = $(this)
+    if ($this.data('fileupload')) return
+    $this.fileupload($this.data())
+      
+    var $target = $(e.target).closest('[data-dismiss="fileupload"],[data-trigger="fileupload"]');
+    if ($target.length > 0) {
+      $target.trigger('click.fileupload')
+      e.preventDefault()
+    }
+  })
+
+}(window.jQuery);