diff --git a/datasette/templates/query_create.html b/datasette/templates/query_create.html index cdf91799..cb14ada4 100644 --- a/datasette/templates/query_create.html +++ b/datasette/templates/query_create.html @@ -94,12 +94,18 @@ form.sql .query-create-sql textarea#sql-editor { .query-create-options input[type=checkbox] { margin: 0; } -.query-create-option-note { +.query-create-option-note, +.query-create-analysis-note { color: #4f5b6d; flex-basis: 100%; font-size: 0.82rem; +} +.query-create-option-note { margin: -0.45rem 0 0; } +.query-create-analysis-note { + margin: 0; +} .query-create-action { margin: 0.35rem 0 1rem; } @@ -160,9 +166,9 @@ form.sql .query-create-sql textarea#sql-editor {
{% if sql and analysis_is_write %} @@ -249,10 +255,25 @@ window.addEventListener("DOMContentLoaded", () => { const submitButton = form ? form.querySelector("[data-query-create-submit]") : null; - const writableCheckbox = form - ? form.querySelector("[data-query-create-writable]") + const analysisNote = form + ? form.querySelector("[data-query-create-analysis-note]") : null; + function updateAnalysisNote(data) { + if (!analysisNote) { + return; + } + if (data.analysis_error) { + analysisNote.textContent = "This query cannot be saved until the SQL is valid."; + } else if (data.has_sql === false) { + analysisNote.textContent = "Enter SQL to analyze this query."; + } else if (data.analysis_is_write) { + analysisNote.textContent = "This query updates data in the database."; + } else { + analysisNote.textContent = "This is a read-only query."; + } + } + window.datasetteSqlParameters.setupSqlParameterRefresh({ form, url: form.dataset.analyzeUrl, @@ -262,9 +283,7 @@ window.addEventListener("DOMContentLoaded", () => { if (submitButton) { submitButton.disabled = data.save_disabled; } - if (writableCheckbox) { - writableCheckbox.checked = data.analysis_is_write; - } + updateAnalysisNote(data); }, onError(error) { window.datasetteSqlAnalysis.renderAnalysis(analysisSection, { @@ -274,9 +293,7 @@ window.addEventListener("DOMContentLoaded", () => { if (submitButton) { submitButton.disabled = true; } - if (writableCheckbox) { - writableCheckbox.checked = false; - } + updateAnalysisNote({ analysis_error: error.message }); }, }); }); diff --git a/tests/test_queries.py b/tests/test_queries.py index 09b41645..f888dda0 100644 --- a/tests/test_queries.py +++ b/tests/test_queries.py @@ -990,6 +990,10 @@ async def test_create_query_ui_and_arbitrary_sql_save_link(): "/data/-/queries/insert?sql=select+*+from+dogs", actor={"id": "root"}, ) + write_create_response = await ds.client.get( + "/data/-/queries/insert?sql=insert+into+dogs+(name)+values+('Cleo')", + actor={"id": "root"}, + ) blank_create_response = await ds.client.get( "/data/-/queries/insert", actor={"id": "root"}, @@ -1005,7 +1009,6 @@ async def test_create_query_ui_and_arbitrary_sql_save_link(): assert create_response.status_code == 200 assert "Create query" in create_response.text - assert "Writable" in create_response.text assert 'type="radio"' not in create_response.text assert 'name="parameters"' not in create_response.text assert 'id="query-parameters"' not in create_response.text @@ -1024,11 +1027,22 @@ async def test_create_query_ui_and_arbitrary_sql_save_link(): assert "renderParameters: false" in create_response.text assert "datasetteSqlAnalysis.renderAnalysis" in create_response.text assert "data-query-create-submit" in create_response.text - assert "data-query-create-writable" in create_response.text + assert "data-query-create-writable" not in create_response.text + assert "data-query-create-sql-type" not in create_response.text + assert "data-query-create-analysis-note" in create_response.text + assert "SQL type:" not in create_response.text + assert ( + 'This is a read-only query.' + in create_response.text + ) + assert "disabled> Writable" not in create_response.text assert ( "Queries marked private can only be seen by you, their creator." in create_response.text ) + assert create_response.text.index( + "This is a read-only query." + ) < create_response.text.index('') assert "| Required permission | ' in create_response.text @@ -1053,6 +1067,12 @@ async def test_create_query_ui_and_arbitrary_sql_save_link(): "
|---|