Yuvipanda has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/154273

Change subject: Use simple textbox for title editing and display
......................................................................

Use simple textbox for title editing and display

- Also make title nullable and do not assign default title
- Remove jquery.jeditable

Change-Id: Iecdfad2aaba5a1be6b42178210810fda9133d9b1
---
M quarry/web/app.py
M quarry/web/static/css/query/view.css
M quarry/web/static/js/query/view.js
D quarry/web/static/vendor/jquery.jeditable.js
M quarry/web/templates/query/list.html
M quarry/web/templates/query/view.html
M tables.sql
7 files changed, 12 insertions(+), 555 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/analytics/quarry/web 
refs/changes/73/154273/1

diff --git a/quarry/web/app.py b/quarry/web/app.py
index 11f7e12..6f30f38 100644
--- a/quarry/web/app.py
+++ b/quarry/web/app.py
@@ -168,7 +168,6 @@
         return redirect("/login?next=/query/new")
     query = Query()
     query.user = g.user
-    query.title = "%s's untitled query #%s" % (g.user.username, 
int(time.time()))
     g.session.add(query)
     g.session.commit()
     return redirect(url_for('query_show', query_id=query.id))
diff --git a/quarry/web/static/css/query/view.css 
b/quarry/web/static/css/query/view.css
index 951fa9f..7b82201 100644
--- a/quarry/web/static/css/query/view.css
+++ b/quarry/web/static/css/query/view.css
@@ -31,6 +31,11 @@
     display: none;
 }
 
+#title {
+    width: 100%;
+    border: none;
+}
+
 #title-actions-container button {
     margin-top: 18px;
     float: right;
diff --git a/quarry/web/static/js/query/view.js 
b/quarry/web/static/js/query/view.js
index 79d7388..a592fa7 100644
--- a/quarry/web/static/js/query/view.js
+++ b/quarry/web/static/js/query/view.js
@@ -7,17 +7,14 @@
     });
 
     if (vars.can_edit) {
-        $('#title').editable(function(value, settings) {
+        $('#title').blur(function() {
             $.post( "/api/query/meta", {
                 query_id: vars.query_id,
-                title: value
+                title: $('#title').val()
             } ).done( function( data ) {
+                // Uh, do nothing
             } );
-            return value;
-        }, {
-            tooltip: 'Click to edit',
-            height: 'None',
-        } );
+        });
     }
 
     $("#un-star-query").click( function() {
diff --git a/quarry/web/static/vendor/jquery.jeditable.js 
b/quarry/web/static/vendor/jquery.jeditable.js
deleted file mode 100644
index 003000e..0000000
--- a/quarry/web/static/vendor/jquery.jeditable.js
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Jeditable - jQuery in place edit plugin
- *
- * Copyright (c) 2006-2009 Mika Tuupola, Dylan Verheul
- *
- * Licensed under the MIT license:
- *   http://www.opensource.org/licenses/mit-license.php
- *
- * Project home:
- *   http://www.appelsiini.net/projects/jeditable
- *
- * Based on editable by Dylan Verheul <dylan_at_dyve.net>:
- *    http://www.dyve.net/jquery/?editable
- *
- */
-
-/**
-  * Version 1.7.1
-  *
-  * ** means there is basic unit tests for this parameter. 
-  *
-  * @name  Jeditable
-  * @type  jQuery
-  * @param String  target             (POST) URL or function to send edited 
content to **
-  * @param Hash    options            additional options 
-  * @param String  options[method]    method to use to send edited content 
(POST or PUT) **
-  * @param Function options[callback] Function to run after submitting edited 
content **
-  * @param String  options[name]      POST parameter name of edited content
-  * @param String  options[id]        POST parameter name of edited div id
-  * @param Hash    options[submitdata] Extra parameters to send when 
submitting edited content.
-  * @param String  options[type]      text, textarea or select (or any 3rd 
party input type) **
-  * @param Integer options[rows]      number of rows if using textarea ** 
-  * @param Integer options[cols]      number of columns if using textarea **
-  * @param Mixed   options[height]    'auto', 'none' or height in pixels **
-  * @param Mixed   options[width]     'auto', 'none' or width in pixels **
-  * @param String  options[loadurl]   URL to fetch input content before 
editing **
-  * @param String  options[loadtype]  Request type for load url. Should be GET 
or POST.
-  * @param String  options[loadtext]  Text to display while loading external 
content.
-  * @param Mixed   options[loaddata]  Extra parameters to pass when fetching 
content before editing.
-  * @param Mixed   options[data]      Or content given as paramameter. String 
or function.**
-  * @param String  options[indicator] indicator html to show when saving
-  * @param String  options[tooltip]   optional tooltip text via title 
attribute **
-  * @param String  options[event]     jQuery event such as 'click' of 
'dblclick' **
-  * @param String  options[submit]    submit button value, empty means no 
button **
-  * @param String  options[cancel]    cancel button value, empty means no 
button **
-  * @param String  options[cssclass]  CSS class to apply to input form. 
'inherit' to copy from parent. **
-  * @param String  options[style]     Style to apply to input form 'inherit' 
to copy from parent. **
-  * @param String  options[select]    true or false, when true text is 
highlighted ??
-  * @param String  options[placeholder] Placeholder text or html to insert 
when element is empty. **
-  * @param String  options[onblur]    'cancel', 'submit', 'ignore' or function 
??
-  *             
-  * @param Function options[onsubmit] function(settings, original) { ... } 
called before submit
-  * @param Function options[onreset]  function(settings, original) { ... } 
called before reset
-  * @param Function options[onerror]  function(settings, original, xhr) { ... 
} called on error
-  *             
-  * @param Hash    options[ajaxoptions]  jQuery Ajax options. See 
docs.jquery.com.
-  *             
-  */
-
-(function($) {
-
-    $.fn.editable = function(target, options) {
-            
-        if ('disable' == target) {
-            $(this).data('disabled.editable', true);
-            return;
-        }
-        if ('enable' == target) {
-            $(this).data('disabled.editable', false);
-            return;
-        }
-        if ('destroy' == target) {
-            $(this)
-                .unbind($(this).data('event.editable'))
-                .removeData('disabled.editable')
-                .removeData('event.editable');
-            return;
-        }
-        
-        var settings = $.extend({}, $.fn.editable.defaults, {target:target}, 
options);
-        
-        /* setup some functions */
-        var plugin   = $.editable.types[settings.type].plugin || function() { 
};
-        var submit   = $.editable.types[settings.type].submit || function() { 
};
-        var buttons  = $.editable.types[settings.type].buttons 
-                    || $.editable.types['defaults'].buttons;
-        var content  = $.editable.types[settings.type].content 
-                    || $.editable.types['defaults'].content;
-        var element  = $.editable.types[settings.type].element 
-                    || $.editable.types['defaults'].element;
-        var reset    = $.editable.types[settings.type].reset 
-                    || $.editable.types['defaults'].reset;
-        var callback = settings.callback || function() { };
-        var onedit   = settings.onedit   || function() { }; 
-        var onsubmit = settings.onsubmit || function() { };
-        var onreset  = settings.onreset  || function() { };
-        var onerror  = settings.onerror  || reset;
-          
-        /* show tooltip */
-        if (settings.tooltip) {
-            $(this).attr('title', settings.tooltip);
-        }
-        
-        settings.autowidth  = 'auto' == settings.width;
-        settings.autoheight = 'auto' == settings.height;
-        
-        return this.each(function() {
-                        
-            /* save this to self because this changes when scope changes */
-            var self = this;  
-                   
-            /* inlined block elements lose their width and height after first 
edit */
-            /* save them for later use as workaround */
-            var savedwidth  = $(self).width();
-            var savedheight = $(self).height();
-            
-            /* save so it can be later used by $.editable('destroy') */
-            $(this).data('event.editable', settings.event);
-            
-            /* if element is empty add something clickable (if requested) */
-            if (!$.trim($(this).html())) {
-                $(this).html(settings.placeholder);
-            }
-            
-            $(this).bind(settings.event, function(e) {
-                
-                /* abort if disabled for this element */
-                if (true === $(this).data('disabled.editable')) {
-                    return;
-                }
-                
-                /* prevent throwing an exeption if edit field is clicked again 
*/
-                if (self.editing) {
-                    return;
-                }
-                
-                /* abort if onedit hook returns false */
-                if (false === onedit.apply(this, [settings, self])) {
-                   return;
-                }
-                
-                /* prevent default action and bubbling */
-                e.preventDefault();
-                e.stopPropagation();
-                
-                /* remove tooltip */
-                if (settings.tooltip) {
-                    $(self).removeAttr('title');
-                }
-                
-                /* figure out how wide and tall we are, saved width and height 
*/
-                /* are workaround for http://dev.jquery.com/ticket/2190 */
-                if (0 == $(self).width()) {
-                    //$(self).css('visibility', 'hidden');
-                    settings.width  = savedwidth;
-                    settings.height = savedheight;
-                } else {
-                    if (settings.width != 'none') {
-                        settings.width = 
-                            settings.autowidth ? $(self).width()  : 
settings.width;
-                    }
-                    if (settings.height != 'none') {
-                        settings.height = 
-                            settings.autoheight ? $(self).height() : 
settings.height;
-                    }
-                }
-                //$(this).css('visibility', '');
-                
-                /* remove placeholder text, replace is here because of IE */
-                if ($(this).html().toLowerCase().replace(/(;|")/g, '') == 
-                    settings.placeholder.toLowerCase().replace(/(;|")/g, '')) {
-                        $(this).html('');
-                }
-                                
-                self.editing    = true;
-                self.revert     = $(self).html();
-                $(self).html('');
-
-                /* create the form object */
-                var form = $('<form />');
-                
-                /* apply css or style or both */
-                if (settings.cssclass) {
-                    if ('inherit' == settings.cssclass) {
-                        form.attr('class', $(self).attr('class'));
-                    } else {
-                        form.attr('class', settings.cssclass);
-                    }
-                }
-
-                if (settings.style) {
-                    if ('inherit' == settings.style) {
-                        form.attr('style', $(self).attr('style'));
-                        /* IE needs the second line or display wont be 
inherited */
-                        form.css('display', $(self).css('display'));           
     
-                    } else {
-                        form.attr('style', settings.style);
-                    }
-                }
-
-                /* add main input element to form and store it in input */
-                var input = element.apply(form, [settings, self]);
-
-                /* set input content via POST, GET, given data or existing 
value */
-                var input_content;
-                
-                if (settings.loadurl) {
-                    var t = setTimeout(function() {
-                        input.disabled = true;
-                        content.apply(form, [settings.loadtext, settings, 
self]);
-                    }, 100);
-
-                    var loaddata = {};
-                    loaddata[settings.id] = self.id;
-                    if ($.isFunction(settings.loaddata)) {
-                        $.extend(loaddata, settings.loaddata.apply(self, 
[self.revert, settings]));
-                    } else {
-                        $.extend(loaddata, settings.loaddata);
-                    }
-                    $.ajax({
-                       type : settings.loadtype,
-                       url  : settings.loadurl,
-                       data : loaddata,
-                       async : false,
-                       success: function(result) {
-                          window.clearTimeout(t);
-                          input_content = result;
-                          input.disabled = false;
-                       }
-                    });
-                } else if (settings.data) {
-                    input_content = settings.data;
-                    if ($.isFunction(settings.data)) {
-                        input_content = settings.data.apply(self, 
[self.revert, settings]);
-                    }
-                } else {
-                    input_content = self.revert; 
-                }
-                content.apply(form, [input_content, settings, self]);
-
-                input.attr('name', settings.name);
-        
-                /* add buttons to the form */
-                buttons.apply(form, [settings, self]);
-         
-                /* add created form to self */
-                $(self).append(form);
-         
-                /* attach 3rd party plugin if requested */
-                plugin.apply(form, [settings, self]);
-
-                /* focus to first visible form element */
-                $(':input:visible:enabled:first', form).focus();
-
-                /* highlight input contents when requested */
-                if (settings.select) {
-                    input.select();
-                }
-        
-                /* discard changes if pressing esc */
-                input.keydown(function(e) {
-                    if (e.keyCode == 27) {
-                        e.preventDefault();
-                        //self.reset();
-                        reset.apply(form, [settings, self]);
-                    }
-                });
-
-                /* discard, submit or nothing with changes when clicking 
outside */
-                /* do nothing is usable when navigating with tab */
-                var t;
-                if ('cancel' == settings.onblur) {
-                    input.blur(function(e) {
-                        /* prevent canceling if submit was clicked */
-                        t = setTimeout(function() {
-                            reset.apply(form, [settings, self]);
-                        }, 500);
-                    });
-                } else if ('submit' == settings.onblur) {
-                    input.blur(function(e) {
-                        /* prevent double submit if submit was clicked */
-                        t = setTimeout(function() {
-                            form.submit();
-                        }, 200);
-                    });
-                } else if ($.isFunction(settings.onblur)) {
-                    input.blur(function(e) {
-                        settings.onblur.apply(self, [input.val(), settings]);
-                    });
-                } else {
-                    input.blur(function(e) {
-                      /* TODO: maybe something here */
-                    });
-                }
-
-                form.submit(function(e) {
-
-                    if (t) { 
-                        clearTimeout(t);
-                    }
-
-                    /* do no submit */
-                    e.preventDefault(); 
-            
-                    /* call before submit hook. */
-                    /* if it returns false abort submitting */                 
   
-                    if (false !== onsubmit.apply(form, [settings, self])) { 
-                        /* custom inputs call before submit hook. */
-                        /* if it returns false abort submitting */
-                        if (false !== submit.apply(form, [settings, self])) { 
-
-                          /* check if given target is function */
-                          if ($.isFunction(settings.target)) {
-                              var str = settings.target.apply(self, 
[input.val(), settings]);
-                              $(self).html(str);
-                              self.editing = false;
-                              callback.apply(self, [self.innerHTML, settings]);
-                              /* TODO: this is not dry */                      
        
-                              if (!$.trim($(self).html())) {
-                                  $(self).html(settings.placeholder);
-                              }
-                          } else {
-                              /* add edited content and id of edited element 
to POST */
-                              var submitdata = {};
-                              submitdata[settings.name] = input.val();
-                              submitdata[settings.id] = self.id;
-                              /* add extra data to be POST:ed */
-                              if ($.isFunction(settings.submitdata)) {
-                                  $.extend(submitdata, 
settings.submitdata.apply(self, [self.revert, settings]));
-                              } else {
-                                  $.extend(submitdata, settings.submitdata);
-                              }
-
-                              /* quick and dirty PUT support */
-                              if ('PUT' == settings.method) {
-                                  submitdata['_method'] = 'put';
-                              }
-
-                              /* show the saving indicator */
-                              $(self).html(settings.indicator);
-                              
-                              /* defaults for ajaxoptions */
-                              var ajaxoptions = {
-                                  type    : 'POST',
-                                  data    : submitdata,
-                                  dataType: 'html',
-                                  url     : settings.target,
-                                  success : function(result, status) {
-                                      if (ajaxoptions.dataType == 'html') {
-                                        $(self).html(result);
-                                      }
-                                      self.editing = false;
-                                      callback.apply(self, [result, settings]);
-                                      if (!$.trim($(self).html())) {
-                                          $(self).html(settings.placeholder);
-                                      }
-                                  },
-                                  error   : function(xhr, status, error) {
-                                      onerror.apply(form, [settings, self, 
xhr]);
-                                  }
-                              };
-                              
-                              /* override with what is given in 
settings.ajaxoptions */
-                              $.extend(ajaxoptions, settings.ajaxoptions);   
-                              $.ajax(ajaxoptions);          
-                              
-                            }
-                        }
-                    }
-                    
-                    /* show tooltip again */
-                    $(self).attr('title', settings.tooltip);
-                    
-                    return false;
-                });
-            });
-            
-            /* privileged methods */
-            this.reset = function(form) {
-                /* prevent calling reset twice when blurring */
-                if (this.editing) {
-                    /* before reset hook, if it returns false abort reseting */
-                    if (false !== onreset.apply(form, [settings, self])) { 
-                        $(self).html(self.revert);
-                        self.editing   = false;
-                        if (!$.trim($(self).html())) {
-                            $(self).html(settings.placeholder);
-                        }
-                        /* show tooltip again */
-                        if (settings.tooltip) {
-                            $(self).attr('title', settings.tooltip);           
     
-                        }
-                    }                    
-                }
-            };            
-        });
-
-    };
-
-
-    $.editable = {
-        types: {
-            defaults: {
-                element : function(settings, original) {
-                    var input = $('<input type="hidden"></input>');            
    
-                    $(this).append(input);
-                    return(input);
-                },
-                content : function(string, settings, original) {
-                    $(':input:first', this).val(string);
-                },
-                reset : function(settings, original) {
-                  original.reset(this);
-                },
-                buttons : function(settings, original) {
-                    var form = this;
-                    if (settings.submit) {
-                        /* if given html string use that */
-                        if (settings.submit.match(/>$/)) {
-                            var submit = $(settings.submit).click(function() {
-                                if (submit.attr("type") != "submit") {
-                                    form.submit();
-                                }
-                            });
-                        /* otherwise use button with given string as text */
-                        } else {
-                            var submit = $('<button type="submit" />');
-                            submit.html(settings.submit);                      
      
-                        }
-                        $(this).append(submit);
-                    }
-                    if (settings.cancel) {
-                        /* if given html string use that */
-                        if (settings.cancel.match(/>$/)) {
-                            var cancel = $(settings.cancel);
-                        /* otherwise use button with given string as text */
-                        } else {
-                            var cancel = $('<button type="cancel" />');
-                            cancel.html(settings.cancel);
-                        }
-                        $(this).append(cancel);
-
-                        $(cancel).click(function(event) {
-                            //original.reset();
-                            if 
($.isFunction($.editable.types[settings.type].reset)) {
-                                var reset = 
$.editable.types[settings.type].reset;                                          
                      
-                            } else {
-                                var reset = 
$.editable.types['defaults'].reset;                                
-                            }
-                            reset.apply(form, [settings, original]);
-                            return false;
-                        });
-                    }
-                }
-            },
-            text: {
-                element : function(settings, original) {
-                    var input = $('<input />');
-                    if (settings.width  != 'none') { 
input.width(settings.width);  }
-                    if (settings.height != 'none') { 
input.height(settings.height); }
-                    /* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
-                    //input[0].setAttribute('autocomplete','off');
-                    input.attr('autocomplete','off');
-                    $(this).append(input);
-                    return(input);
-                }
-            },
-            textarea: {
-                element : function(settings, original) {
-                    var textarea = $('<textarea />');
-                    if (settings.rows) {
-                        textarea.attr('rows', settings.rows);
-                    } else if (settings.height != "none") {
-                        textarea.height(settings.height);
-                    }
-                    if (settings.cols) {
-                        textarea.attr('cols', settings.cols);
-                    } else if (settings.width != "none") {
-                        textarea.width(settings.width);
-                    }
-                    $(this).append(textarea);
-                    return(textarea);
-                }
-            },
-            select: {
-               element : function(settings, original) {
-                    var select = $('<select />');
-                    $(this).append(select);
-                    return(select);
-                },
-                content : function(data, settings, original) {
-                    /* If it is string assume it is json. */
-                    if (String == data.constructor) {      
-                        eval ('var json = ' + data);
-                    } else {
-                    /* Otherwise assume it is a hash already. */
-                        var json = data;
-                    }
-                    for (var key in json) {
-                        if (!json.hasOwnProperty(key)) {
-                            continue;
-                        }
-                        if ('selected' == key) {
-                            continue;
-                        } 
-                        var option = $('<option 
/>').val(key).append(json[key]);
-                        $('select', this).append(option);    
-                    }                    
-                    /* Loop option again to set selected. IE needed this... */ 
-                    $('select', this).children().each(function() {
-                        if ($(this).val() == json['selected'] || 
-                            $(this).text() == $.trim(original.revert)) {
-                                $(this).attr('selected', 'selected');
-                        }
-                    });
-                }
-            }
-        },
-
-        /* Add new input type */
-        addInputType: function(name, input) {
-            $.editable.types[name] = input;
-        }
-    };
-
-    // publicly accessible defaults
-    $.fn.editable.defaults = {
-        name       : 'value',
-        id         : 'id',
-        type       : 'text',
-        width      : 'auto',
-        height     : 'auto',
-        event      : 'click.editable',
-        onblur     : 'cancel',
-        loadtype   : 'GET',
-        loadtext   : 'Loading...',
-        placeholder: 'Click to edit',
-        loaddata   : {},
-        submitdata : {},
-        ajaxoptions: {}
-    };
-
-})(jQuery);
diff --git a/quarry/web/templates/query/list.html 
b/quarry/web/templates/query/list.html
index 9a085b1..d31e70a 100644
--- a/quarry/web/templates/query/list.html
+++ b/quarry/web/templates/query/list.html
@@ -15,7 +15,7 @@
         <tbody>
         {% for query in queries %}
             <tr>
-                <td><a href="/query/{{query.id}}">{{query.title}}</a></td>
+                <td><a href="/query/{{query.id}}">{% if query.title 
%}{{query.title}}{% else %}Untitled query #{{query.id}}{% endif %}</a></td>
                 <td><a 
href="/{{query.user.username}}">{{query.user.username}}</a></td>
                 <td>{{query.latest_rev.latest_run.status_message}}</td>
                 <td>{{query.latest_rev.latest_run.timestamp|timesince}}</td>
diff --git a/quarry/web/templates/query/view.html 
b/quarry/web/templates/query/view.html
index 818e48f..764b646 100644
--- a/quarry/web/templates/query/view.html
+++ b/quarry/web/templates/query/view.html
@@ -4,7 +4,6 @@
 <link rel="stylesheet" href="/static/vendor/codemirror-4.3/lib/codemirror.css">
 <link rel="stylesheet" href="/static/vendor/codemirror-4.3/theme/monokai.css">
 <link rel="stylesheet" href="/static/css/query/view.css">
-<script src="/static/vendor/jquery.jeditable.js"> </script>
 <script src="/static/vendor/swig-1.4.1.min.js"> </script>
 <script src="/static/vendor/codemirror-4.3/lib/codemirror.js"> </script>
 <script src="/static/vendor/codemirror-4.3/mode/sql/sql.js"> </script>
@@ -15,7 +14,7 @@
 <div id="content" class="container {% if jsvars.can_edit %}edit{% else 
%}no-edit{% endif %} {% if jsvars.is_starred %}starred{% endif %} {% if 
query.published %}published {% endif %}">
     <div class="row" id="title-container">
         <div class="col-md-10">
-            <h2 id='title'>{{query.title}}</h2>
+            <h2><input type="textbox" id="title" {% if jsvars.can_edit 
%}placeholder="Click to add title..."{% else %}readonly{% endif %} value="{% if 
query.title %}{{query.title}}{% endif %}"> </input></h2>
         </div>
         <div class="col-md-2" id="title-actions-container">
             {% if user and not jsvars.can_edit %}
diff --git a/tables.sql b/tables.sql
index d993819..41e7609 100644
--- a/tables.sql
+++ b/tables.sql
@@ -11,7 +11,7 @@
 CREATE TABLE query(
     id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
     user_id INT UNSIGNED NOT NULL,
-    title VARCHAR(1024) BINARY NOT NULL,
+    title VARCHAR(1024) BINARY,
     latest_rev_id INT UNSIGNED,
     last_touched TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE 
CURRENT_TIMESTAMP,
     published SMALLINT DEFAULT 0,

-- 
To view, visit https://gerrit.wikimedia.org/r/154273
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iecdfad2aaba5a1be6b42178210810fda9133d9b1
Gerrit-PatchSet: 1
Gerrit-Project: analytics/quarry/web
Gerrit-Branch: master
Gerrit-Owner: Yuvipanda <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to