mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Much improved column menu display logic, refs #981
* Menu links now take into account existing querystring * No longer shows facet option for primary key columns * Conditionally displays sort/sort-desc if already sorted * Does not show facet option if already faceted by this
This commit is contained in:
parent
fd0b00330f
commit
0f2626868b
4 changed files with 82 additions and 16 deletions
|
|
@ -13,16 +13,37 @@ var DROPDOWN_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="14" heig
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
// Feature detection
|
||||||
|
if (!window.URLSearchParams) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function getParams() {
|
||||||
|
return new URLSearchParams(location.search);
|
||||||
|
}
|
||||||
|
function paramsToUrl(params) {
|
||||||
|
var s = params.toString();
|
||||||
|
return s ? ('?' + s) : '';
|
||||||
|
}
|
||||||
function sortDescUrl(column) {
|
function sortDescUrl(column) {
|
||||||
return '?_sort_desc=' + encodeURIComponent(column);
|
var params = getParams();
|
||||||
|
params.set('_sort_desc', column);
|
||||||
|
params.delete('_sort');
|
||||||
|
return paramsToUrl(params);
|
||||||
}
|
}
|
||||||
function sortAscUrl(column) {
|
function sortAscUrl(column) {
|
||||||
return '?_sort=' + encodeURIComponent(column);
|
var params = getParams();
|
||||||
|
params.set('_sort', column);
|
||||||
|
params.delete('_sort_desc');
|
||||||
|
return paramsToUrl(params);
|
||||||
}
|
}
|
||||||
function facetUrl(column) {
|
function facetUrl(column) {
|
||||||
return '?_facet=' + encodeURIComponent(column);
|
var params = getParams();
|
||||||
|
params.append('_facet', column);
|
||||||
|
return paramsToUrl(params);
|
||||||
|
}
|
||||||
|
function isFacetedBy(column) {
|
||||||
|
return getParams().getAll('_facet').includes(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
function iconClicked(ev) {
|
function iconClicked(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
var th = ev.target;
|
var th = ev.target;
|
||||||
|
|
@ -33,12 +54,25 @@ var DROPDOWN_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="14" heig
|
||||||
var menuTop = rect.bottom + window.scrollY;
|
var menuTop = rect.bottom + window.scrollY;
|
||||||
var menuLeft = rect.left + window.scrollX;
|
var menuLeft = rect.left + window.scrollX;
|
||||||
var column = th.getAttribute('data-column');
|
var column = th.getAttribute('data-column');
|
||||||
menu.querySelector('a.dropdown-sort-desc').setAttribute('href', sortDescUrl(column));
|
var params = getParams();
|
||||||
menu.querySelector('a.dropdown-sort-asc').setAttribute('href', sortAscUrl(column));
|
var sort = menu.querySelector('a.dropdown-sort-asc');
|
||||||
/* Only show facet if it's not the first column */
|
var sortDesc = menu.querySelector('a.dropdown-sort-desc');
|
||||||
var isFirstColumn = th.parentElement.querySelector('th:first-of-type') == th;
|
|
||||||
var facetItem = menu.querySelector('a.dropdown-facet');
|
var facetItem = menu.querySelector('a.dropdown-facet');
|
||||||
if (isFirstColumn) {
|
if (params.get('_sort') == column) {
|
||||||
|
sort.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
sort.style.display = 'block';
|
||||||
|
sort.setAttribute('href', sortAscUrl(column));
|
||||||
|
}
|
||||||
|
if (params.get('_sort_desc') == column) {
|
||||||
|
sortDesc.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
sortDesc.style.display = 'block';
|
||||||
|
sortDesc.setAttribute('href', sortDescUrl(column));
|
||||||
|
}
|
||||||
|
/* Only show facet if it's not the first column, not selected, not a PK */
|
||||||
|
var isFirstColumn = th.parentElement.querySelector('th:first-of-type') == th;
|
||||||
|
if (isFirstColumn || params.getAll('_facet').includes(column) || th.getAttribute('data-is-pk') == '1') {
|
||||||
facetItem.style.display = 'none';
|
facetItem.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
facetItem.style.display = 'block';
|
facetItem.style.display = 'block';
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{% for column in display_columns %}
|
{% for column in display_columns %}
|
||||||
<th class="col-{{ column.name|to_css_class }}" scope="col" data-column="{{ column.name }}">
|
<th class="col-{{ column.name|to_css_class }}" scope="col" data-column="{{ column.name }}" data-is-pk="{% if column.is_pk %}1{% else %}0{% endif %}">
|
||||||
{% if not column.sortable %}
|
{% if not column.sortable %}
|
||||||
{{ column.name }}
|
{{ column.name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,18 @@ class RowTableShared(DataView):
|
||||||
db = self.ds.databases[database]
|
db = self.ds.databases[database]
|
||||||
table_metadata = self.ds.table_metadata(database, table)
|
table_metadata = self.ds.table_metadata(database, table)
|
||||||
sortable_columns = await self.sortable_columns_for_table(database, table, True)
|
sortable_columns = await self.sortable_columns_for_table(database, table, True)
|
||||||
columns = [
|
|
||||||
{"name": r[0], "sortable": r[0] in sortable_columns} for r in description
|
|
||||||
]
|
|
||||||
pks = await db.primary_keys(table)
|
pks = await db.primary_keys(table)
|
||||||
|
pks_for_display = pks
|
||||||
|
if not pks_for_display:
|
||||||
|
pks_for_display = ["rowid"]
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
"name": r[0],
|
||||||
|
"sortable": r[0] in sortable_columns,
|
||||||
|
"is_pk": r[0] in pks_for_display,
|
||||||
|
}
|
||||||
|
for r in description
|
||||||
|
]
|
||||||
column_to_foreign_key_table = {
|
column_to_foreign_key_table = {
|
||||||
fk["column"]: fk["other_table"]
|
fk["column"]: fk["other_table"]
|
||||||
for fk in await db.foreign_keys_for_table(table)
|
for fk in await db.foreign_keys_for_table(table)
|
||||||
|
|
|
||||||
|
|
@ -344,21 +344,37 @@ def test_sort_links(app_client):
|
||||||
]
|
]
|
||||||
assert [
|
assert [
|
||||||
{
|
{
|
||||||
"attrs": {"class": ["col-Link"], "data-column": "Link", "scope": "col"},
|
"attrs": {
|
||||||
|
"class": ["col-Link"],
|
||||||
|
"data-column": "Link",
|
||||||
|
"data-is-pk": "0",
|
||||||
|
"scope": "col",
|
||||||
|
},
|
||||||
"a_href": None,
|
"a_href": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attrs": {"class": ["col-pk1"], "data-column": "pk1", "scope": "col"},
|
"attrs": {
|
||||||
|
"class": ["col-pk1"],
|
||||||
|
"data-column": "pk1",
|
||||||
|
"data-is-pk": "1",
|
||||||
|
"scope": "col",
|
||||||
|
},
|
||||||
"a_href": None,
|
"a_href": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attrs": {"class": ["col-pk2"], "data-column": "pk2", "scope": "col"},
|
"attrs": {
|
||||||
|
"class": ["col-pk2"],
|
||||||
|
"data-column": "pk2",
|
||||||
|
"data-is-pk": "1",
|
||||||
|
"scope": "col",
|
||||||
|
},
|
||||||
"a_href": None,
|
"a_href": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attrs": {
|
"attrs": {
|
||||||
"class": ["col-content"],
|
"class": ["col-content"],
|
||||||
"data-column": "content",
|
"data-column": "content",
|
||||||
|
"data-is-pk": "0",
|
||||||
"scope": "col",
|
"scope": "col",
|
||||||
},
|
},
|
||||||
"a_href": None,
|
"a_href": None,
|
||||||
|
|
@ -367,6 +383,7 @@ def test_sort_links(app_client):
|
||||||
"attrs": {
|
"attrs": {
|
||||||
"class": ["col-sortable"],
|
"class": ["col-sortable"],
|
||||||
"data-column": "sortable",
|
"data-column": "sortable",
|
||||||
|
"data-is-pk": "0",
|
||||||
"scope": "col",
|
"scope": "col",
|
||||||
},
|
},
|
||||||
"a_href": "sortable?_sort_desc=sortable",
|
"a_href": "sortable?_sort_desc=sortable",
|
||||||
|
|
@ -375,6 +392,7 @@ def test_sort_links(app_client):
|
||||||
"attrs": {
|
"attrs": {
|
||||||
"class": ["col-sortable_with_nulls"],
|
"class": ["col-sortable_with_nulls"],
|
||||||
"data-column": "sortable_with_nulls",
|
"data-column": "sortable_with_nulls",
|
||||||
|
"data-is-pk": "0",
|
||||||
"scope": "col",
|
"scope": "col",
|
||||||
},
|
},
|
||||||
"a_href": "sortable?_sort=sortable_with_nulls",
|
"a_href": "sortable?_sort=sortable_with_nulls",
|
||||||
|
|
@ -383,12 +401,18 @@ def test_sort_links(app_client):
|
||||||
"attrs": {
|
"attrs": {
|
||||||
"class": ["col-sortable_with_nulls_2"],
|
"class": ["col-sortable_with_nulls_2"],
|
||||||
"data-column": "sortable_with_nulls_2",
|
"data-column": "sortable_with_nulls_2",
|
||||||
|
"data-is-pk": "0",
|
||||||
"scope": "col",
|
"scope": "col",
|
||||||
},
|
},
|
||||||
"a_href": "sortable?_sort=sortable_with_nulls_2",
|
"a_href": "sortable?_sort=sortable_with_nulls_2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attrs": {"class": ["col-text"], "data-column": "text", "scope": "col"},
|
"attrs": {
|
||||||
|
"class": ["col-text"],
|
||||||
|
"data-column": "text",
|
||||||
|
"data-is-pk": "0",
|
||||||
|
"scope": "col",
|
||||||
|
},
|
||||||
"a_href": "sortable?_sort=text",
|
"a_href": "sortable?_sort=text",
|
||||||
},
|
},
|
||||||
] == attrs_and_link_attrs
|
] == attrs_and_link_attrs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue