[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