New sortable_columns option in metadata.json to control sort options

You can now explicitly set which columns in a table can be used for sorting
using the _sort and _sort_desc arguments using metadata.json:

    {
        "databases": {
            "database1": {
                "tables": {
                    "example_table": {
                        "sortable_columns": [
                            "height",
                            "weight"
                        ]
                    }
                }
            }
        }
    }

Refs #189
This commit is contained in:
Simon Willison 2018-04-08 21:58:25 -07:00 committed by Simon Willison
commit b13f0986f2
7 changed files with 93 additions and 23 deletions

View file

@ -456,10 +456,27 @@ class DatabaseDownload(BaseView):
class RowTableShared(BaseView):
def sortable_columns_for_table(self, name, table, use_rowid):
table_metadata = self.ds.metadata.get(
'databases', {}
).get(name, {}).get('tables', {}).get(table, {})
if 'sortable_columns' in table_metadata:
sortable_columns = set(table_metadata['sortable_columns'])
else:
table_info = self.ds.inspect()[name]['tables'].get(table) or {}
sortable_columns = set(table_info.get('columns', []))
if use_rowid:
sortable_columns.add('rowid')
return sortable_columns
async def display_columns_and_rows(self, database, table, description, rows, link_column=False, expand_foreign_keys=True):
"Returns columns, rows for specified table - including fancy foreign key treatment"
info = self.ds.inspect()[database]
columns = [r[0] for r in description]
sortable_columns = self.sortable_columns_for_table(database, table, True)
columns = [{
'name': r[0],
'sortable': r[0] in sortable_columns,
} for r in description]
tables = info['tables']
table_info = tables.get(table) or {}
pks = await self.pks_for_table(database, table)
@ -505,7 +522,8 @@ class RowTableShared(BaseView):
)
),
})
for value, column in zip(row, columns):
for value, column_dict in zip(row, columns):
column = column_dict['name']
if (column, value) in expanded:
other_table, label = expanded[(column, value)]
display_value = jinja2.Markup(
@ -533,7 +551,10 @@ class RowTableShared(BaseView):
cell_rows.append(cells)
if link_column:
columns = ['Link'] + columns
columns = [{
'name': 'Link',
'sortable': False,
}] + columns
return columns, cell_rows
@ -623,7 +644,7 @@ class TableView(RowTableShared):
if not is_view:
table_info = info[name]['tables'][table]
table_rows = table_info['count']
sortable_columns = set(table_info['columns'])
sortable_columns = self.sortable_columns_for_table(name, table, use_rowid)
# Allow for custom sort order
sort = special_args.get('_sort')
@ -885,6 +906,8 @@ class RowView(RowTableShared):
display_columns, display_rows = await self.display_columns_and_rows(
name, table, description, rows, link_column=False, expand_foreign_keys=True
)
for column in display_columns:
column['sortable'] = False
return {
'database_hash': hash,
'foreign_key_tables': await self.foreign_key_tables(name, table, pk_values),
@ -895,7 +918,6 @@ class RowView(RowTableShared):
'_rows_and_columns-row-{}-{}.html'.format(to_css_class(name), to_css_class(table)),
'_rows_and_columns.html',
],
'disable_sort': True,
'enumerate': enumerate,
'metadata': self.ds.metadata.get(
'databases', {}

View file

@ -1,15 +1,15 @@
<table>
<thead>
<tr>
{% for i, column in enumerate(display_columns) %}
{% for column in display_columns %}
<th scope="col">
{% if i == 0 or disable_sort %}
{{ column }}
{% if not column.sortable %}
{{ column.name }}
{% else %}
{% if column == sort %}
<a href="{{ path_with_added_args(request, {'_sort_desc': column, '_sort': None, '_next': None}) }}" rel="nofollow">{{ column }}&nbsp;</a>
{% if column.name == sort %}
<a href="{{ path_with_added_args(request, {'_sort_desc': column.name, '_sort': None, '_next': None}) }}" rel="nofollow">{{ column.name }}&nbsp;</a>
{% else %}
<a href="{{ path_with_added_args(request, {'_sort': column, '_sort_desc': None, '_next': None}) }}" rel="nofollow">{{ column }}{% if column == sort_desc %}&nbsp;▲{% endif %}</a>
<a href="{{ path_with_added_args(request, {'_sort': column.name, '_sort_desc': None, '_next': None}) }}" rel="nofollow">{{ column.name }}{% if column.name == sort_desc %}&nbsp;▲{% endif %}</a>
{% endif %}
{% endif %}
</th>

View file

@ -8,7 +8,7 @@
<style>
@media only screen and (max-width: 576px) {
{% for column in display_columns %}
td:nth-of-type({{ loop.index }}):before { content: "{{ column|escape_css_string }}"; }
td:nth-of-type({{ loop.index }}):before { content: "{{ column.name|escape_css_string }}"; }
{% endfor %}
}
</style>