[ckan-changes] commit/ckan: 5 new changesets

Bitbucket commits-noreply at bitbucket.org
Fri Sep 16 20:04:36 UTC 2011


5 new changesets in ckan:

http://bitbucket.org/okfn/ckan/changeset/72044660fcf6/
changeset:   72044660fcf6
branch:      feature-1294-ux-improvements-dataset
user:        zephod
date:        2011-09-16 16:22:09
summary:     [ux][xs]: Remove defunct template variable.
affected #:  1 file (-1 bytes)

--- a/ckan/controllers/package.py	Fri Sep 16 14:52:22 2011 +0100
+++ b/ckan/controllers/package.py	Fri Sep 16 15:22:09 2011 +0100
@@ -85,7 +85,6 @@
         c.groups_available = get_action('group_list_authz')(context, data_dict)
         c.licences = [('', '')] + model.Package.get_license_options()
         c.is_sysadmin = Authorizer().is_sysadmin(c.user)
-        c.resource_columns = model.Resource.get_columns()
 
         ## This is messy as auths take domain object not data_dict
         context_pkg = context.get('package',None)


http://bitbucket.org/okfn/ckan/changeset/1b8a83e5dfc0/
changeset:   1b8a83e5dfc0
branch:      feature-1294-ux-improvements-dataset
user:        zephod
date:        2011-09-16 16:26:06
summary:     [ux,close-branch]:
affected #:  0 files (-1 bytes)

http://bitbucket.org/okfn/ckan/changeset/d43e0335e8c3/
changeset:   d43e0335e8c3
user:        zephod
date:        2011-09-16 16:28:02
summary:     [merge,from-branch][m]: Closed 1294 branch. Pulling in minor UX changes; preview removed from logic layer.
affected #:  16 files (-1 bytes)

--- a/ckan/controllers/package.py	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/controllers/package.py	Fri Sep 16 15:28:02 2011 +0100
@@ -85,7 +85,6 @@
         c.groups_available = get_action('group_list_authz')(context, data_dict)
         c.licences = [('', '')] + model.Package.get_license_options()
         c.is_sysadmin = Authorizer().is_sysadmin(c.user)
-        c.resource_columns = model.Resource.get_columns()
 
         ## This is messy as auths take domain object not data_dict
         context_pkg = context.get('package',None)


--- a/ckan/lib/package_saver.py	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/lib/package_saver.py	Fri Sep 16 15:28:02 2011 +0100
@@ -9,25 +9,10 @@
 # Todo: Factor out unused original_name argument.
 
 class PackageSaver(object):
-    '''Use this to validate, preview and save packages to the db.
+    '''Use this to validate and save packages to the db.
     @param log_message: optional - only supply this if you want it validated
     @param author: optional - only supply this if you want it validated
     '''
-    @classmethod
-    def render_preview(cls, fs, log_message=None, author=None, client=None):
-        '''Renders a package on the basis of a fieldset - perfect for
-        preview of form data.
-        Note that the actual calling of render('package/read') is left
-        to the caller.'''
-        pkg = cls._preview_pkg(fs, log_message, author, client=client)
-
-        pkg_dict = table_dictize(pkg, {'model': model})
-        pkg_dict['extras'] = []
-        c.pkg = pkg
-        for key, value in pkg.extras.iteritems():
-            pkg_dict['extras'].append(dict(key=key, value=value))
-
-        cls.render_package(pkg_dict, {'package': pkg})
 
     # TODO: rename to something more correct like prepare_for_render
     @classmethod
@@ -69,47 +54,17 @@
             c.pkg_revision_not_latest = c.pkg_dict[u'revision_id'] != c.pkg.revision.id
 
     @classmethod
-    def _preview_pkg(cls, fs, log_message=None, author=None, client=None):
-        '''Previews the POST data (associated with a package edit)
-        @input c.error
-        @input fs      FieldSet with the param data bound to it
-        @param log_message: only supply this if you want it validated
-        @param author: only supply this if you want it validated
-        @return package object
-        '''
-        try:
-            out = cls._update(fs, log_message,
-                              author, commit=False, client=client)
-        except ValidationException, e:
-            raise ValidationException(*e)
-        finally:
-            # While the package is still in the session, touch the relations
-            # so that they load (they are set to lazy load) because we will
-            # need to use their values later when we render the package
-            # object (i.e. preview it).
-            fs.model.license
-            fs.model.groups
-            fs.model.ratings
-            fs.model.extras
-            fs.model.resources
-            # remove everything from session so nothing can get saved
-            # accidentally
-            model.Session.remove()
-        return out
-
-    @classmethod
     def commit_pkg(cls, fs, log_message, author, client=None):
         '''Writes the POST data (associated with a package edit) to the
         database
         @input c.error
         @input fs      FieldSet with the param data bound to it
         '''
-        cls._update(fs, log_message, author, commit=True, client=client)
+        cls._update(fs, log_message, author, client=client)
 
     @classmethod
-    def _update(cls, fs, log_message, author, commit=True, client=None):
+    def _update(cls, fs, log_message, author, client=None):
         # Todo: Consolidate log message field (and validation).
-        # Todo: Separate out the preview line of execution, it's confusing.
         rev = None
         # validation
         errors = cls._revision_validation(log_message)
@@ -129,13 +84,9 @@
             model.Session.rollback()
             raise
         else:
-            # only commit if desired and it validates ok
-            if commit and validates:
+            # only commit if it validates ok
+            if validates:
                 model.Session.commit()
-            elif validates:
-                # i.e. preview
-                pkg = fs.model
-                return pkg
         if rev and 'true' == config.get('changeset.auto_commit', '').strip():
             try:
                 from ckan.model.changeset import ChangesetRegister


--- a/ckan/logic/action/create.py	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/logic/action/create.py	Fri Sep 16 15:28:02 2011 +0100
@@ -36,13 +36,11 @@
 
     model = context['model']
     user = context['user']
-    preview = context.get('preview', False)
     schema = context.get('schema') or default_create_package_schema()
     model.Session.remove()
     model.Session()._context = context
 
-    if not preview:
-        check_access('package_create',context,data_dict)
+    check_access('package_create',context,data_dict)
 
     data, errors = validate(data_dict, schema, context)
 
@@ -50,39 +48,33 @@
         model.Session.rollback()
         raise ValidationError(errors, package_error_summary(errors))
 
-    if not preview:
-        rev = model.repo.new_revision()
-        rev.author = user
-        if 'message' in context:
-            rev.message = context['message']
-        else:
-            rev.message = _(u'REST API: Create object %s') % data.get("name")
+    rev = model.repo.new_revision()
+    rev.author = user
+    if 'message' in context:
+        rev.message = context['message']
+    else:
+        rev.message = _(u'REST API: Create object %s') % data.get("name")
 
     pkg = package_dict_save(data, context)
     admins = []
     if user:
         admins = [model.User.by_name(user.decode('utf8'))]
 
-    if not preview:
-        model.setup_default_user_roles(pkg, admins)
-        for item in PluginImplementations(IPackageController):
-            item.create(pkg)
-        model.repo.commit()        
+    model.setup_default_user_roles(pkg, admins)
+    for item in PluginImplementations(IPackageController):
+        item.create(pkg)
+    model.repo.commit()        
 
-    ## need to let rest api create and preview
+    ## need to let rest api create
     context["package"] = pkg
     ## this is added so that the rest controller can make a new location 
     context["id"] = pkg.id
     log.debug('Created object %s' % str(pkg.name))
-    if not preview:
-        return package_dictize(pkg, context) 
-    else:
-        return data
+    return package_dictize(pkg, context) 
 
 def package_create_validate(context, data_dict):
     model = context['model']
     user = context['user']
-    preview = context.get('preview', False)
     schema = context.get('schema') or default_create_package_schema()
     model.Session.remove()
     model.Session()._context = context


--- a/ckan/logic/action/update.py	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/logic/action/update.py	Fri Sep 16 15:28:02 2011 +0100
@@ -193,7 +193,6 @@
     user = context['user']
     
     id = data_dict["id"]
-    preview = context.get('preview', False)
     schema = context.get('schema') or default_update_package_schema()
     model.Session.remove()
     model.Session()._context = context
@@ -214,29 +213,25 @@
         model.Session.rollback()
         raise ValidationError(errors, package_error_summary(errors))
 
-    if not preview:
-        rev = model.repo.new_revision()
-        rev.author = user
-        if 'message' in context:
-            rev.message = context['message']
-        else:
-            rev.message = _(u'REST API: Update object %s') % data.get("name")
+    rev = model.repo.new_revision()
+    rev.author = user
+    if 'message' in context:
+        rev.message = context['message']
+    else:
+        rev.message = _(u'REST API: Update object %s') % data.get("name")
 
     pkg = package_dict_save(data, context)
 
-    if not preview:
-        for item in PluginImplementations(IPackageController):
-            item.edit(pkg)
-        model.repo.commit()        
-        return package_dictize(pkg, context)
-    return data
+    for item in PluginImplementations(IPackageController):
+        item.edit(pkg)
+    model.repo.commit()        
+    return package_dictize(pkg, context)
 
 def package_update_validate(context, data_dict):
     model = context['model']
     user = context['user']
     
     id = data_dict["id"]
-    preview = context.get('preview', False)
     schema = context.get('schema') or default_update_package_schema()
     model.Session.remove()
     model.Session()._context = context


--- a/ckan/public/css/forms.css	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/public/css/forms.css	Fri Sep 16 15:28:02 2011 +0100
@@ -114,6 +114,37 @@
     color: #555;
     font-size: 90%;
   }
+
+form table thead th.form-label {
+    width: 23%;
+    display: none;
+}
+form table thead th.form-value {
+    width: 27%;
+    display: none;
+}
+form table tbody tr td.form-label,
+form table tbody tr td.form-value {
+  font-size: 0.92em;
+  line-height: 1.5em;
+  padding-top: 0;
+  padding-bottom: 4px;
+  white-space: nowrap;
+  background: inherit;
+}
+form table tbody tr td.form-label {
+  text-align: right; 
+  font-weight: bold;
+  padding-right: 4px;
+  vertical-align: middle;
+}
+form table tbody tr td.form-value {
+  padding-left: 4px; 
+  border-left: 1px dashed #aaa;
+}
+form table td.form-value input {
+  width: 100%;
+}
  
 label.has-errors, label.fieldWithErrors {
   font-weight: bold;


--- a/ckan/public/css/style.css	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/public/css/style.css	Fri Sep 16 15:28:02 2011 +0100
@@ -240,7 +240,7 @@
   background-color: #FEFEF2;
 }
 
-tbody tr td.table-empty {
+tbody tr.table-empty td {
   background: #f8f8f8;
   border: 1px solid #eee;
   font-style: italic;
@@ -562,11 +562,14 @@
 /* = Search boxes = */
 /* ================ */
 
+form.dataset-search {
+  margin-bottom: 35px;
+}
+
 form.dataset-search input.search {
-  width: 99%;
+  width: 100%;
   font-size: 1.2em;
   margin: 0px;
-  -webkit-appearance: textfield;
   
   border: 1px solid #ccc;
   padding: 0.5em;
@@ -575,7 +578,7 @@
      -moz-border-radius: 5px; 
   -webkit-border-radius: 5px; 
           border-radius: 5px; 
-  -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; 
+ -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; 
 }
 
 .dataset-search input.button {
@@ -776,25 +779,31 @@
 }
 
 
-table.resource-table tbody tr td {
+table.resource-table tbody tr td.resource-expand-link,
+table.resource-table tbody tr td.resource-is-changed {
   vertical-align: top;
 }
-table.resource-table td.resource-summary {
-  vertical-align: middle;
-}
 
-td.resource-expanded dl{
-  margin-bottom: 5px;
+td.resource-expanded {
+  padding: 8px 0 8px 0;
 }
 td.resource-expand-link {
   padding-top: 6px;
   text-align: center;
 }
-th.resource-is-changed, td.resource-is-changed {
+th.resource-expand-link,
+td.resource-expand-link,
+th.resource-is-changed, 
+td.resource-is-changed {
   text-align: center;
   padding: 8px 0 0 0;
   width: 20px;
 }
+
+div.inner table {
+  margin-bottom: 0;
+}
+
 /* ====================== */
 /* = Add Resources Page = */
 /* ====================== */
@@ -803,6 +812,10 @@
   width: 60%;
 }
 
+button.delete-resource {
+  float: right;
+}
+
 /* ==================== */
 /* = Add Dataset Page = */
 /* ==================== */


--- a/ckan/public/scripts/application.js	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/public/scripts/application.js	Fri Sep 16 15:28:02 2011 +0100
@@ -386,16 +386,14 @@
       window.onbeforeunload = null;
     });
 
-
-
-    // Create Backbone view for adding resources
+    // Tabbed view for adding resources
     var $el=this.el.find('.resource-add');
     this.addView=new CKAN.View.ResourceAdd({
       collection: this.model.get('resources'),
       el: $el
     });
 
-    // Create Resource Edit list
+    // Table for editing resources
     var $el=this.el.find('.resource-table.edit');
     this.resourceList=new CKAN.View.ResourceEditList({
       collection: this.model.get('resources'),
@@ -403,7 +401,6 @@
     });
 
     this.render();
-
   },
 
 
@@ -430,25 +427,50 @@
     // Have to trash entire content; some stuff was there on page load
     this.el.find('tbody').empty();
     this.collection.each(this.addRow);
+
+    if (this.collection.isEmpty()) {
+      $tr = $('<tr />').addClass('table-empty');
+      $tr.html('<td></td><td colspan="4">(none)</td>');
+      this.el.find('tbody').append($tr);
+    }
   },
 
   nextIndex: function() {
     var maxId=-1;
     this.el.find('input').each(function(idx,input) {
-      var myId = parseInt($(input).attr('name').split('__')[1])
-      maxId = Math.max(myId, maxId);
+      var splitName=$(input).attr('name').split('__');
+      if (splitName.length>1) {
+        var myId = parseInt(splitName[1])
+        maxId = Math.max(myId, maxId);
+      }
     });
     return maxId+1;
   },
 
   addRow: function(resource) {
+    // Strip placeholder row
+    this.el.find('tr.table-empty').remove();
+
     // TODO tidy up so the view creates its own elements
     var $tr = $('<tr />');
-    this.el.find('tbody').append($tr);
+
+    // Captured by an inner function
+    var self = this;
+
+    this.el.find('tbody.resource-table').append($tr);
     var _view = new CKAN.View.ResourceEdit({
       model: resource,
       el: $tr,
-      position: this.nextIndex()
+      position: this.nextIndex(),
+      deleteResource: function() {
+        // Passing down a capture to remove the resource
+        $tr.remove();
+        
+        self.collection.remove(resource);
+        if (self.collection.isEmpty()) {
+          self.render();
+        }
+      }
     });
     _view.render();
   },
@@ -462,11 +484,12 @@
     _.bindAll(this, 'render', 'toggleExpanded');
     var self = this;
     this.model.bind('change', function() { self.hasChanged=true; });
-    this.model.bind('change', this.render);
+    this.model.bind('change', this.render());
     this.position = this.options.position;
 
     this.expanded = this.model.isNew();
     this.hasChanged = this.model.isNew();
+    this.animate = this.model.isNew();
   },
 
   render: function() {
@@ -480,6 +503,10 @@
     if (this.expanded) {
       this.el.find('a.resource-expand-link').hide();
       this.el.find('.resource-summary').hide();
+      if (this.animate) {
+        this.el.find('.resource-expanded .inner').hide();
+        this.el.find('.resource-expanded .inner').show('slow');
+      }
     }
     else {
       this.el.find('a.resource-collapse-link').hide();
@@ -489,11 +516,18 @@
     if (!this.hasChanged) {
       this.el.find('img.resource-is-changed').hide();
     }
+    this.animate = false;
   },
 
   events: {
     'click a.resource-expand-link': 'toggleExpanded',
-    'click a.resource-collapse-link': 'toggleExpanded'
+    'click a.resource-collapse-link': 'toggleExpanded',
+    'click .delete-resource': 'clickDelete'
+  },
+
+  clickDelete: function(e) {
+    e.preventDefault();
+    this.options.deleteResource();
   },
 
   saveData: function() {
@@ -520,6 +554,7 @@
     e.preventDefault();
 
     this.expanded = !this.expanded;
+    this.animate = true;
     // Closing the form; update the model fields
     if (!this.expanded) {
       this.saveData();


--- a/ckan/public/scripts/templates.js	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/public/scripts/templates.js	Fri Sep 16 15:28:02 2011 +0100
@@ -87,13 +87,30 @@
     ${resource.description} \
   </td> \
   <td class="resource-expanded" colspan="3"> \
-    <dl> \
-      <dt>Name</dt> \
-      <dd> \
+    <div class="inner"> \
+    <table> \
+      <thead> \
+      <th class="form-label"></th> \
+      <th class="form-value"></th> \
+      <th class="form-label"></th> \
+      <th class="form-value"></th> \
+      </thead> \
+      <tbody> \
+      <tr> \
+      <td style="display: none;" class="form-label">Name</td> \
+      <td style="display: none;" class="form-value" colspan="3"> \
         <input name="resources__${num}__name" type="text" value="${resource.name}" class="long" /> \
-      </dd> \
-      <dt>Url</dt> \
-      <dd> \
+      </td> \
+      </tr> \
+      <tr> \
+      <td class="form-label">Description</td> \
+      <td class="form-value" colspan="3"> \
+        <input name="resources__${num}__description" type="text" value="${resource.description}" class="long" /> \
+      </td> \
+      </tr> \
+      <tr> \
+      <td class="form-label">Url</td> \
+      <td class="form-value" colspan="3"> \
       {{if resource.resource_type=="file.upload"}} \
         ${resource.url} \
         <input name="resources__${num}__url" type="hidden" value="${resource.url}" /> \
@@ -101,33 +118,15 @@
       {{if resource.resource_type!="file.upload"}} \
         <input name="resources__${num}__url" type="text" value="${resource.url}" class="long" /> \
       {{/if}} \
-      </dd> \
-      <dt>Format</dt> \
-      <dd> \
+      </td> \
+      </tr> \
+      <tr> \
+      <td class="form-label">Format</td> \
+      <td class="form-value"> \
         <input name="resources__${num}__format" type="text" value="${resource.format}" class="long autocomplete-format" /> \
-      </dd> \
-      <dt>Description</dt> \
-      <dd> \
-        <input name="resources__${num}__description" type="text" value="${resource.description}" class="long" /> \
-      </dd> \
-      <dt>Size (bytes)</dt> \
-      <dd> \
-        <input name="resources__${num}__size" type="text" value="${resource.size}" class="long" /> \
-      </dd> \
-      <dt>Mimetype</dt> \
-      <dd> \
-        <input name="resources__${num}__mimetype" type="text" value="${resource.mimetype}" /> \
-      </dd> \
-      <dt>Mimetype-inner</dt> \
-      <dd> \
-        <input name="resources__${num}__mimetype_inner" type="text" value="${resource.mimetype_inner}" /> \
-      </dd> \
-      <dt>Last Modified</dt> \
-      <dd> \
-        <input name="resources__${num}__last_modified" type="text" value="${resource.last_modified}" /> \
-      </dd> \
-      <dt>Resource Type</dt> \
-      <dd> \
+      </td> \
+      <td class="form-label">Resource Type</td> \
+      <td class="form-value"> \
       {{if resource.resource_type=="file.upload"}} \
         ${resource.resource_type} \
         <input name="resources__${num}__resource_type" type="hidden" value="${resource.resource_type}" /> \
@@ -135,18 +134,44 @@
       {{if resource.resource_type!="file.upload"}} \
         <input name="resources__${num}__resource_type" type="text" value="${resource.resource_type}" /> \
       {{/if}} \
-      </dd> \
-      <dt>Hash</dt> \
-      <dd> \
+      </td> \
+      </tr> \
+      <tr> \
+      <td class="form-label">Size (bytes)</td> \
+      <td class="form-value"> \
+        <input name="resources__${num}__size" type="text" value="${resource.size}" class="long" /> \
+      </td> \
+      <td class="form-label">Mimetype</td> \
+      <td class="form-value"> \
+        <input name="resources__${num}__mimetype" type="text" value="${resource.mimetype}" /> \
+      </td> \
+      </tr> \
+      <tr> \
+      <td class="form-label">Last Modified</td> \
+      <td class="form-value"> \
+        <input name="resources__${num}__last_modified" type="text" value="${resource.last_modified}" /> \
+      </td> \
+      <td class="form-label">Mimetype-inner</td> \
+      <td class="form-value"> \
+        <input name="resources__${num}__mimetype_inner" type="text" value="${resource.mimetype_inner}" /> \
+      </td> \
+      </tr> \
+      <tr> \
+      <td class="form-label">Hash</td> \
+      <td class="form-value"> \
         ${resource.hash || "Unknown"} \
         <input name="resources__${num}__hash" type="hidden" value="${resource.hash}" /> \
-      </dd> \
-      <dt>ID</dt> \
-      <dd> \
+      </td> \
+      <td class="form-label">ID</td> \
+      <td class="form-value"> \
         ${resource.id} \
         <input name="resources__${num}__id" type="hidden" value="${resource.id}" /> \
-      </dd> \
-    </dl> \
+      </td> \
+      </tr> \
+    </tbody> \
+    </table> \
+    <button class="delete-resource pretty-button danger">Delete Resource</button> \
+    </div> \
   </td> \
   <td class="resource-is-changed"> \
     <img src="/images/icons/add.png" title="This resource has unsaved changes." class="resource-is-changed" /> \


--- a/ckan/templates/package/form_fields.html	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/templates/package/form_fields.html	Fri Sep 16 15:28:02 2011 +0100
@@ -51,9 +51,7 @@
                 <script type="text/javascript">
 //<![CDATA[
 $(document).ready(function () {
-    if (!$('#preview').length) {
-        $("#${field.renderer.name}").focus();
-    }
+      $("#${field.renderer.name}").focus();
 });
 //]]></script>


--- a/ckan/templates/package/layout.html	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/templates/package/layout.html	Fri Sep 16 15:28:02 2011 +0100
@@ -6,7 +6,7 @@
   ><py:match path="minornavigation">
-    <py:if test="c.pkg and not c.is_preview">
+    <py:if test="c.pkg"><ul class="tabbed"><li>${h.subnav_link(c, h.icon('package') + _('View'), controller='package', action='read', id=c.pkg.name)}</li><li py:if="h.check_access('package_update',{'id':c.pkg.id})">


--- a/ckan/templates/package/new.html	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/templates/package/new.html	Fri Sep 16 15:28:02 2011 +0100
@@ -13,9 +13,7 @@
     <script type="text/javascript">
       jQuery(document).ready(function($) {
         CKAN.Utils.PackageSlugCreator.create($('#title'), $('#name'));
-        if (!$('#preview').length) {
-          $("#title").focus();
-        }
+        $("#title").focus();
       });
     </script></py:def>


--- a/ckan/templates/package/new_package_form.html	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/templates/package/new_package_form.html	Fri Sep 16 15:28:02 2011 +0100
@@ -91,14 +91,14 @@
   <table class="resource-table edit"><thead><tr>
-        <th></th>
+        <th class="resource-expand-link"></th><th class="field_req resource-url">URL*</th><th class="field_opt resource-format">Format</th><th class="field_opt resource-description">Description</th><th class="field_opt resource-is-changed"></th></tr></thead>
-    <tbody>
+    <tbody class="resource-table"><py:for each="num, res in enumerate(data.get('resources', []))"><tr class="resource-summary"><td class="resource-expand-link">
@@ -142,6 +142,9 @@
         </td></tr></py:for>
+      <py:if test="not len(data.get('resources', []))">
+        <tr class="table-empty"><td colspan="5">(none)</td></tr>
+      </py:if></tbody></table>
 


--- a/ckan/templates/package/read_core.html	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/templates/package/read_core.html	Fri Sep 16 15:28:02 2011 +0100
@@ -36,7 +36,7 @@
           </tr></py:for><py:if test="not len(c.pkg_dict.get('resources', []))">
-          <tr><td colspan="2" class="table-empty">(none)</td></tr>
+          <tr class="table-empty"><td colspan="2">(none)</td></tr></py:if></table></div>
@@ -70,7 +70,7 @@
           <td class="dataset-details" property="rdf:value">${value}</td></tr><py:if test="not len(c.pkg_extras)">
-          <tr><td colspan="2" class="table-empty">(none)</td></tr>
+          <tr class="table-empty"><td colspan="2">(none)</td></tr></py:if></tbody></table>


--- a/ckan/templates/package/search_form.html	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/templates/package/search_form.html	Fri Sep 16 15:28:02 2011 +0100
@@ -6,16 +6,17 @@
   ><form id="dataset-search" class="dataset-search" action="${h.url_for(controller='package', action='search', id=None)}" method="GET">
-  <input type="search" class="search" name="q" value="${c.q}" autocomplete="off" results="5" placeholder="Search..." />
+  <input type="search" class="search" name="q" value="${c.q}" autocomplete="off" results="0" placeholder="Search..." /><span py:if="c.fields"><py:for each="(k, v) in c.fields"><input type="hidden" name="${k}" value="${v}" /></py:for></span>
-  <div class="dataset-search-filters">Filter by <label for="open_only" class="inline">${h.checkbox(name='open_only', checked=c.open_only)} datasets with open licenses</label>
+  <!-- Feature disabled for a cleaner page. TODO Remove entirely from backend? -->
+  <div style="display: none;" class="dataset-search-filters">Filter by <label for="open_only" class="inline">${h.checkbox(name='open_only', checked=c.open_only)} datasets with open licenses</label><label for="downloadable_only" class="inline">${h.checkbox(name='downloadable_only', checked=c.downloadable_only)} datasets with downloads</label>
-  <input type="submit" value="${_('Search')}" class="button" /></div>
+  <input type="submit" value="${_('Search')}" class="pretty-button primary button" /></form></html>


--- a/ckan/tests/html_check.py	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/tests/html_check.py	Fri Sep 16 15:28:02 2011 +0100
@@ -23,10 +23,6 @@
         'strips html to just the <div id="main"> section'
         return self.named_div('main', html)
 
-    def preview_div(self, html):
-        'strips html to just the <div id="preview"> section'
-        return self.named_div('preview', html)
-
     def sidebar(self, html):
         'strips html to just the <div id="primary"> section'
         return self.named_div('primary', html)


--- a/ckan/tests/misc/test_package_saver.py	Thu Sep 15 17:50:37 2011 +0100
+++ b/ckan/tests/misc/test_package_saver.py	Fri Sep 16 15:28:02 2011 +0100
@@ -34,9 +34,7 @@
         data = ckan.forms.add_to_package_dict(
             ckan.forms.get_package_dict(fs=fs, user_editable_groups=[]), self.params)
         fs = fs.bind(model.Package, data=data)
-        pkg = PackageSaver()._preview_pkg(fs, '', '')
 
-        self._check_preview_pkg(pkg, self.params)
         assert not model.Package.by_name(u'testname')
 
     def test_edit(self):
@@ -60,8 +58,6 @@
                 ckan.forms.get_package_dict(pkg=pkg, fs=fs, user_editable_groups=[]), self.params,
                     pkg.id)
         fs = fs.bind(pkg, data=data)
-        pkg2 = PackageSaver()._preview_pkg(fs, u'name_before', pkg.id)
-        self._check_preview_pkg(pkg2, self.params)
 
         # Check nothing has changed in the model
         assert model.Package.by_name(u'name_before')
@@ -69,27 +65,4 @@
         assert not model.Tag.by_name(u'three')
         resources = model.Session.query(model.Resource).filter_by(url=u'dlu2c').first()
         assert resources is None, resources
-
-    def _check_preview_pkg(self, pkg, params):
-        for key, value in params.items():
-            if key == u'license':
-                assert pkg.license_id == value
-                assert pkg.license.id == value
-            elif key == u'license_id':
-                assert pkg.license_id == value
-                assert pkg.license.id == value
-            elif key == u'tags':
-                reqd_tags = value.split()
-                assert len(pkg.tags) == len(reqd_tags)
-                for tag in pkg.tags:
-                    assert tag.name in reqd_tags
-            elif key == u'resources':
-                assert pkg.resources[0].url == value[0]['url']
-                assert pkg.resources[0].format == value[0]['format']
-                assert pkg.resources[1].url == value[1]['url']
-                assert pkg.resources[1].format == value[1]['format']
-            else:
-                assert getattr(pkg, key) == value, \
-                       'Package has "%s"="%s" when it should be %s' % \
-                       (key, getattr(pkg, key), value)
         


http://bitbucket.org/okfn/ckan/changeset/d5babc3629cf/
changeset:   d5babc3629cf
branch:      feature-1348-ux-tweaks
user:        zephod
date:        2011-09-16 16:58:54
summary:     Stripped 'filter by openness' and 'filter by downloadable' from the frontend & backend.
affected #:  9 files (-1 bytes)

--- a/ckan/controllers/package.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/controllers/package.py	Fri Sep 16 15:58:54 2011 +0100
@@ -110,8 +110,6 @@
             abort(401, _('Not authorized to see this page'))
 
         q = c.q = request.params.get('q') # unicode format (decoded from utf8)
-        c.open_only = request.params.get('open_only')
-        c.downloadable_only = request.params.get('downloadable_only')
         c.query_error = False
         try:
             page = int(request.params.get('page', 1))
@@ -144,7 +142,7 @@
         try:
             c.fields = []
             for (param, value) in request.params.items():
-                if not param in ['q', 'open_only', 'downloadable_only', 'page'] \
+                if not param in ['q', 'page'] \
                         and len(value) and not param.startswith('_'):
                     c.fields.append((param, value))
 
@@ -157,8 +155,6 @@
                          'limit':limit,
                          'offset':(page-1)*limit,
                          'return_objects':True,
-                         'filter_by_openness':c.open_only,
-                         'filter_by_downloadable':c.downloadable_only,
                         }
 
             query = get_action('package_search')(context,data_dict)


--- a/ckan/lib/search/__init__.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/lib/search/__init__.py	Fri Sep 16 15:58:54 2011 +0100
@@ -9,8 +9,6 @@
 DEFAULT_OPTIONS = {
     'limit': 20,
     'offset': 0,
-    'filter_by_openness': False,
-    'filter_by_downloadable': False,
     # about presenting the results
     'order_by': 'rank',
     'return_objects': False,


--- a/ckan/lib/search/common.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/lib/search/common.py	Fri Sep 16 15:58:54 2011 +0100
@@ -148,7 +148,7 @@
     to the query terms (such as limits, etc.).
     """
     
-    BOOLEAN_OPTIONS = ['filter_by_downloadable', 'filter_by_openness', 'all_fields']
+    BOOLEAN_OPTIONS = ['all_fields']
     INTEGER_OPTIONS = ['offset', 'limit']
 
     def __init__(self, **kwargs):


--- a/ckan/lib/search/sql.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/lib/search/sql.py	Fri Sep 16 15:58:54 2011 +0100
@@ -152,15 +152,6 @@
                         q = q.filter(make_like(model_attr, term))
                 else:
                     q = self._filter_by_extra(q, field, terms)
-            
-        # Filter for options
-        if self.options.filter_by_downloadable:
-            q = q.join('resource_groups_all', 'resources_all', aliased=True)
-            q = q.filter(sqlalchemy.and_(
-                model.Resource.state==model.State.ACTIVE,
-                model.ResourceGroup.package_id==model.Package.id))
-        if self.options.filter_by_openness:
-            q = q.filter(model.Package.license_id.in_(self.open_licenses))
         
         order_by = self.options.order_by
         if order_by is not None:


--- a/ckan/logic/action/get.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/logic/action/get.py	Fri Sep 16 15:58:54 2011 +0100
@@ -582,8 +582,6 @@
     limit=data_dict.get('limit',20)
     offset=data_dict.get('offset',0)
     return_objects=data_dict.get('return_objects',False)
-    filter_by_openness=data_dict.get('filter_by_openness',False)
-    filter_by_downloadable=data_dict.get('filter_by_downloadable',False)
 
     query = query_for(model.Package)
     query.run(query=q,
@@ -592,8 +590,6 @@
               limit=limit,
               offset=offset,
               return_objects=return_objects,
-              filter_by_openness=filter_by_openness,
-              filter_by_downloadable=filter_by_downloadable,
               username=user)
 
     results = []


--- a/ckan/templates/package/search_form.html	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/templates/package/search_form.html	Fri Sep 16 15:58:54 2011 +0100
@@ -12,10 +12,6 @@
     <input type="hidden" name="${k}" value="${v}" /></py:for></span>
-  <!-- Feature disabled for a cleaner page. TODO Remove entirely from backend? -->
-  <div style="display: none;" class="dataset-search-filters">Filter by <label for="open_only" class="inline">${h.checkbox(name='open_only', checked=c.open_only)} datasets with open licenses</label>
-  <label for="downloadable_only" class="inline">${h.checkbox(name='downloadable_only', checked=c.downloadable_only)} datasets with downloads</label>
-  </div><input type="submit" value="${_('Search')}" class="pretty-button primary button" /></form>
 


--- a/ckan/tests/functional/api/test_package_search.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/tests/functional/api/test_package_search.py	Fri Sep 16 15:58:54 2011 +0100
@@ -49,8 +49,8 @@
         # uri parameters
         check(UnicodeMultiDict({'q': '', 'ref': 'boris'}),
               {"q": "", "ref": "boris"})
-        check(UnicodeMultiDict({'filter_by_openness': '1'}),
-              {'filter_by_openness': '1'})
+        check(UnicodeMultiDict({}),
+              {})
         # uri json
         check(UnicodeMultiDict({'qjson': '{"q": "", "ref": "boris"}'}),
               {"q": "", "ref": "boris"})
@@ -286,36 +286,6 @@
         res_dict = self.data_from_res(res)
         assert_equal(res_dict['count'], 3)
 
-    def test_12_filter_by_openness_qjson(self):
-        query = {'q': '', 'filter_by_openness': '1'}
-        json_query = self.dumps(query)
-        offset = self.base_url + '?qjson=%s' % json_query
-        res = self.app.get(offset, status=200)
-        res_dict = self.data_from_res(res)
-        assert_equal(res_dict['count'], 2)
-        self.assert_results(res_dict, (u'annakarenina', u'testpkg'))
-
-    def test_12_filter_by_openness_q(self):
-        offset = self.base_url + '?filter_by_openness=1'
-        res = self.app.get(offset, status=200)
-        res_dict = self.data_from_res(res)
-        assert_equal(res_dict['count'], 2)
-        self.assert_results(res_dict, (u'annakarenina', u'testpkg'))
-
-    def test_12_filter_by_openness_off_qjson(self):
-        query = {'q': '', 'filter_by_openness': '0'}
-        json_query = self.dumps(query)
-        offset = self.base_url + '?qjson=%s' % json_query
-        res = self.app.get(offset, status=200)
-        res_dict = self.data_from_res(res)
-        assert_equal(res_dict['count'], 3)
-
-    def test_12_filter_by_openness_off_q(self):
-        offset = self.base_url + '?filter_by_openness=0'
-        res = self.app.get(offset, status=200)
-        res_dict = self.data_from_res(res)
-        assert_equal(res_dict['count'], 3)
-
     def test_13_just_groups(self):
         offset = self.base_url + '?groups=roger'
         res = self.app.get(offset, status=200)


--- a/ckan/tests/functional/test_package.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/tests/functional/test_package.py	Fri Sep 16 15:58:54 2011 +0100
@@ -336,9 +336,9 @@
         res = self.app.get(offset)
         assert 'Search - ' in res
         self._check_search_results(res, 'annakarenina', ['<strong>1</strong>', 'A Novel By Tolstoy'] )
-        self._check_search_results(res, 'warandpeace', ['<strong>0</strong>'], only_downloadable=True )
-        self._check_search_results(res, 'warandpeace', ['<strong>0</strong>'], only_open=True )
-        self._check_search_results(res, 'annakarenina', ['<strong>1</strong>'], only_open=True, only_downloadable=True )
+        self._check_search_results(res, 'warandpeace', ['<strong>1</strong>'])
+        self._check_search_results(res, 'warandpeace', ['<strong>1</strong>'])
+        self._check_search_results(res, 'annakarenina', ['<strong>1</strong>'])
         # check for something that also finds tags ...
         self._check_search_results(res, 'russian', ['<strong>2</strong>'])
 
@@ -359,11 +359,9 @@
         results_page = self.main_div(results_page)
         assert '<strong>0</strong>' in results_page, results_page
 
-    def _check_search_results(self, page, terms, requireds, only_open=False, only_downloadable=False):
+    def _check_search_results(self, page, terms, requireds):
         form = page.forms['dataset-search']
         form['q'] = terms.encode('utf8') # paste doesn't handle this!
-        form['open_only'] = only_open
-        form['downloadable_only'] = only_downloadable
         results_page = form.submit()
         assert 'Search - ' in results_page, results_page
         results_page = self.main_div(results_page)


--- a/ckan/tests/lib/test_package_search.py	Fri Sep 16 15:28:02 2011 +0100
+++ b/ckan/tests/lib/test_package_search.py	Fri Sep 16 15:58:54 2011 +0100
@@ -289,10 +289,8 @@
     def teardown_class(self):
         model.repo.rebuild_db()
 
-    def _check_search_results(self, terms, expected_count, expected_packages=[], only_open=False, only_downloadable=False):
+    def _check_search_results(self, terms, expected_count, expected_packages=[]):
         options = QueryOptions()
-        options.filter_by_openness = only_open
-        options.filter_by_downloadable = only_downloadable
         result = self.backend.query_for(model.Package).run(query=unicode(terms))
         pkgs = result['results']
         count = result['count']
@@ -311,9 +309,9 @@
         self._check_search_results('groups:david', 2 )
         self._check_search_results('groups:roger', 1 )
         self._check_search_results('groups:lenny', 0 )
-        self._check_search_results('annakarenina', 1, ['annakarenina'], True, False )
-        self._check_search_results('annakarenina', 1, ['annakarenina'], False, True )
-        self._check_search_results('annakarenina', 1, ['annakarenina'], True, True )
+        self._check_search_results('annakarenina', 1, ['annakarenina'] )
+        self._check_search_results('annakarenina', 1, ['annakarenina'] )
+        self._check_search_results('annakarenina', 1, ['annakarenina'] )
         
 
 class TestGeographicCoverage(TestController):


http://bitbucket.org/okfn/ckan/changeset/cc0ad47293e5/
changeset:   cc0ad47293e5
branch:      feature-1348-ux-tweaks
user:        zephod
date:        2011-09-16 22:03:51
summary:     [ux,templates][m]: Highlighting the active tab in the #minornavigation pane.
affected #:  5 files (-1 bytes)

--- a/ckan/public/css/style.css	Fri Sep 16 15:58:54 2011 +0100
+++ b/ckan/public/css/style.css	Fri Sep 16 21:03:51 2011 +0100
@@ -176,6 +176,22 @@
 #minornavigation ul.tabbed li.action {
   float: right;
 }
+#minornavigation li {
+  border: 1px solid transparent;
+}
+#minornavigation li.current-tab {
+  background: #000;
+  background-color: #fff;
+  border: 1px solid #aaa;
+     -moz-border-radius: 5px; 
+  -webkit-border-radius: 5px; 
+          border-radius: 5px; 
+}
+#minornavigation li.current-tab a,
+#minornavigation li.current-tab a:hover,
+#minornavigation li.current-tab a:visited {
+  color: #222;
+}
 
 /* Side bar widgets */
 ul.widget-list {
@@ -262,13 +278,14 @@
 
 #minornavigation ul {
   list-style: none; 
-  padding: 7px;
+  padding: 1px;
   margin: 0;
 }
 
 #minornavigation ul li {
   display: inline-block;
-  margin-right: 2em;
+  margin-right: 3px;
+  padding: 5px 11px 5px 9px
 }
 
 #minornavigation ul li a {


--- a/ckan/templates/authorization_group/layout.html	Fri Sep 16 15:58:54 2011 +0100
+++ b/ckan/templates/authorization_group/layout.html	Fri Sep 16 21:03:51 2011 +0100
@@ -8,11 +8,11 @@
 
   <py:match path="minornavigation" py:if="c.authorization_group"><ul class="tabbed">
-    <li>${h.subnav_link(c, h.icon('authorization_group') + _('View'), controller='authorization_group', action='read', id=c.authorization_group.name or c.authorization_group.id)}</li>
-    <li py:if="h.check_access('authorization_group_update',{'id':c.authorization_group.id})">
+    <li py:attrs="{'class':'current-tab'} if c.action=='read' else {}">${h.subnav_link(c, h.icon('authorization_group') + _('View'), controller='authorization_group', action='read', id=c.authorization_group.name or c.authorization_group.id)}</li>
+    <li py:attrs="{'class':'current-tab'} if c.action=='edit' else {}" py:if="h.check_access('authorization_group_update',{'id':c.authorization_group.id})">
       ${h.subnav_link(c, h.icon('authorization_group_edit') + _('Edit'), controller='authorization_group', action='edit', id=c.authorization_group.name or c.authorization_group.id)}
     </li>
-    <li py:if="h.check_access('authorization_group_edit_permissions',{'id':c.authorization_group.id})">
+    <li py:attrs="{'class':'current-tab'} if c.action=='authz' else {}" py:if="h.check_access('authorization_group_edit_permissions',{'id':c.authorization_group.id})">
       ${h.subnav_link(c, h.icon('lock') + _('Authorization'), controller='authorization_group', action='authz', id=c.authorization_group.name or c.authorization_group.id)}
     </li></ul>


--- a/ckan/templates/group/layout.html	Fri Sep 16 15:58:54 2011 +0100
+++ b/ckan/templates/group/layout.html	Fri Sep 16 21:03:51 2011 +0100
@@ -23,12 +23,12 @@
 
   <py:match path="minornavigation" py:if="c.group"><ul class="tabbed">
-    <li>${h.subnav_link(c, h.icon('group') + _('View'), controller='group', action='read', id=c.group.name)}</li>
-    <li py:if="h.check_access('group_update',{'id':c.group.id})">
+    <li py:attrs="{'class':'current-tab'} if c.action=='read' else {}">${h.subnav_link(c, h.icon('group') + _('View'), controller='group', action='read', id=c.group.name)}</li>
+    <li py:attrs="{'class':'current-tab'} if c.action=='edit' else {}" py:if="h.check_access('group_update',{'id':c.group.id})">
       ${h.subnav_link(c, h.icon('group_edit') + _('Edit'), controller='group', action='edit', id=c.group.name)}
     </li>
-    <li>${h.subnav_link(c, h.icon('page_white_stack') + _('History'), controller='group', action='history', id=c.group.name)}</li>
-    <li py:if="h.check_access('group_edit_permissions',{'id':c.group.id})">
+    <li py:attrs="{'class':'current-tab'} if c.action=='history' else {}">${h.subnav_link(c, h.icon('page_white_stack') + _('History'), controller='group', action='history', id=c.group.name)}</li>
+    <li py:attrs="{'class':'current-tab'} if c.action=='authz' else {}" py:if="h.check_access('group_edit_permissions',{'id':c.group.id})">
       ${h.subnav_link(c, h.icon('lock') + _('Authorization'), controller='group', action='authz', id=c.group.name)}
     </li><li class="action">


--- a/ckan/templates/package/layout.html	Fri Sep 16 15:58:54 2011 +0100
+++ b/ckan/templates/package/layout.html	Fri Sep 16 21:03:51 2011 +0100
@@ -8,12 +8,12 @@
   <py:match path="minornavigation"><py:if test="c.pkg"><ul class="tabbed">
-      <li>${h.subnav_link(c, h.icon('package') + _('View'), controller='package', action='read', id=c.pkg.name)}</li>
-      <li py:if="h.check_access('package_update',{'id':c.pkg.id})">
+      <li py:attrs="{'class':'current-tab'} if c.action=='read' else {}">${h.subnav_link(c, h.icon('package') + _('View'), controller='package', action='read', id=c.pkg.name)}</li>
+      <li py:attrs="{'class':'current-tab'} if c.action=='edit' else {}" py:if="h.check_access('package_update',{'id':c.pkg.id})">
           ${h.subnav_link(c, h.icon('package_edit') + _('Edit'), controller='package', action='edit', id=c.pkg.name)}
       </li>
-      <li>${h.subnav_link(c, h.icon('page_stack') + _('History'), controller='package', action='history', id=c.pkg.name)}</li>
-      <li py:if="h.check_access('package_edit_permissions',{'id':c.pkg.id})">
+      <li py:attrs="{'class':'current-tab'} if c.action=='history' else {}">${h.subnav_link(c, h.icon('page_stack') + _('History'), controller='package', action='history', id=c.pkg.name)}</li>
+      <li py:attrs="{'class':'current-tab'} if c.action=='authz' else {}" py:if="h.check_access('package_edit_permissions',{'id':c.pkg.id})">
         ${h.subnav_link(c, h.icon('lock') + _('Authorization'), controller='package', action='authz', id=c.pkg.name)}
       </li><li class="action">


--- a/ckan/templates/revision/list.html	Fri Sep 16 15:58:54 2011 +0100
+++ b/ckan/templates/revision/list.html	Fri Sep 16 21:03:51 2011 +0100
@@ -7,7 +7,7 @@
 
   <py:match path="minornavigation"><ul class="tabbed">
-      <li>
+      <li class="current-tab">
         ${h.subnav_link(c,_('Home'), controller='revision', action='index')}</li><li class="action">
       ${h.subnav_link(c, h.icon('atom_feed') + _('Subscribe'),

Repository URL: https://bitbucket.org/okfn/ckan/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list