From 1359de65c02d383a6f0a6e46048503b6a9fcfdcb Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 8 Jun 2026 20:18:16 -0700 Subject: [PATCH] Tweaks to delete query flow Animated demo: https://github.com/simonw/datasette/pull/2764#issuecomment-4655694668 Refs #2760 --- datasette/templates/query_delete.html | 12 ++++++- datasette/templates/query_list.html | 50 +++++++++++++-------------- datasette/views/stored_queries.py | 4 +-- tests/test_queries.py | 19 +++++++++- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/datasette/templates/query_delete.html b/datasette/templates/query_delete.html index d1691039..4d0699a7 100644 --- a/datasette/templates/query_delete.html +++ b/datasette/templates/query_delete.html @@ -32,6 +32,16 @@ display: flex; gap: 1rem; } +.query-delete-form input[type=submit] { + background: linear-gradient(180deg, #d73a31 0%, #b42318 100%); + border-color: #b42318; + font-weight: 700; +} +.query-delete-form input[type=submit]:hover, +.query-delete-form input[type=submit]:focus { + background: linear-gradient(180deg, #c3342b 0%, #971c14 100%); + border-color: #971c14; +} {% endblock %} @@ -60,7 +70,7 @@
{{ query.sql }}
-
+

Cancel diff --git a/datasette/templates/query_list.html b/datasette/templates/query_list.html index fa4859b1..a8c9a391 100644 --- a/datasette/templates/query_list.html +++ b/datasette/templates/query_list.html @@ -205,32 +205,32 @@

Queries

- - -
- - - {% if queries %} +
+ +
+ + +
diff --git a/datasette/views/stored_queries.py b/datasette/views/stored_queries.py index 43f6f1a8..2753f876 100644 --- a/datasette/views/stored_queries.py +++ b/datasette/views/stored_queries.py @@ -641,6 +641,4 @@ class QueryDeleteView(BaseView): "Query “{}” deleted".format(existing.title or query_name), self.ds.INFO, ) - return Response.redirect( - self.ds.urls.path(self.ds.urls.database(db.name) + "/-/queries") - ) + return Response.redirect(self.ds.urls.path(self.ds.urls.database(db.name))) diff --git a/tests/test_queries.py b/tests/test_queries.py index 7ea1a7a0..6e9bcbdb 100644 --- a/tests/test_queries.py +++ b/tests/test_queries.py @@ -3,6 +3,7 @@ import re from html import unescape import pytest +from bs4 import BeautifulSoup as Soup from datasette.app import Datasette from datasette.resources import DatabaseResource, QueryResource @@ -712,6 +713,10 @@ async def test_query_list_search_filter_and_html(): "/data/-/queries?is_private=1", actor={"id": "root"}, ) + no_results_response = await ds.client.get( + "/data/-/queries?q=nope", + actor={"id": "root"}, + ) assert html_response.status_code == 200 assert "Demo query 02" in html_response.text @@ -799,6 +804,13 @@ async def test_query_list_search_filter_and_html(): 'Not private0' not in filtered_private_response.text ) + assert no_results_response.status_code == 200 + assert "No queries found." in no_results_response.text + assert 'class="query-list-filters core"' not in no_results_response.text + assert 'id="query-search"' not in no_results_response.text + assert 'class="query-list-facets"' not in no_results_response.text + assert "

Mode

" not in no_results_response.text + assert "

Visibility

" not in no_results_response.text @pytest.mark.asyncio @@ -1274,6 +1286,11 @@ async def test_query_delete_confirmation_and_form_delete(): assert get_response.status_code == 200 assert "Are you sure" in get_response.text assert "select * from dogs" in get_response.text + soup = Soup(get_response.text, "html.parser") + form = soup.select_one("form.query-delete-form") + assert form is not None + assert "core" in form["class"] + assert form.select_one('input[type="submit"][value="Delete query"]') is not None post_response = await ds.client.post( "/data/saved/-/delete", @@ -1281,7 +1298,7 @@ async def test_query_delete_confirmation_and_form_delete(): data={}, ) assert post_response.status_code == 302 - assert post_response.headers["location"] == "/data/-/queries" + assert post_response.headers["location"] == "/data" assert await ds.get_query("data", "saved") is None