mirror of
https://github.com/simonw/datasette.git
synced 2026-06-15 13:36:58 +02:00
Add foreign key autocomplete to row forms
Expose single-primary-key foreign key autocomplete URLs in table page metadata and load the autocomplete component when needed. Enhance insert and edit dialogs to wrap foreign-key inputs with the autocomplete web component, show linked selected-row labels, reserve metadata space, and keep the dropdown as a fixed overlay above modal chrome. Add an explicit _initial=1 autocomplete mode for empty-field starter suggestions while keeping blank q responses empty by default, with tests for the endpoint and table metadata.
This commit is contained in:
parent
aa5fb7be3d
commit
574290fb23
8 changed files with 474 additions and 20 deletions
|
|
@ -53,6 +53,53 @@ async def test_autocomplete_blank_q_returns_no_results():
|
|||
assert response.status_code == 200
|
||||
assert response.json() == {"rows": []}
|
||||
|
||||
response = await ds.client.get("/autocomplete_blank/people/-/autocomplete")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"rows": []}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_autocomplete_initial_returns_latest_rows():
|
||||
ds = Datasette(memory=True)
|
||||
db = ds.add_memory_database("autocomplete_initial")
|
||||
await db.execute_write_script("""
|
||||
create table people (
|
||||
id integer primary key,
|
||||
name text
|
||||
);
|
||||
insert into people (id, name) values
|
||||
(1, 'Alice'),
|
||||
(2, 'Bob'),
|
||||
(3, 'Cleo');
|
||||
""")
|
||||
|
||||
response = await ds.client.get(
|
||||
"/autocomplete_initial/people/-/autocomplete?_initial=1"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"rows": [
|
||||
{"pks": {"id": 3}, "label": "Cleo"},
|
||||
{"pks": {"id": 2}, "label": "Bob"},
|
||||
{"pks": {"id": 1}, "label": "Alice"},
|
||||
]
|
||||
}
|
||||
|
||||
response = await ds.client.get(
|
||||
"/autocomplete_initial/people/-/autocomplete?q=&_initial=1"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"rows": [
|
||||
{"pks": {"id": 3}, "label": "Cleo"},
|
||||
{"pks": {"id": 2}, "label": "Bob"},
|
||||
{"pks": {"id": 1}, "label": "Alice"},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_autocomplete_escapes_like_characters():
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,61 @@ async def test_table_insert_action_includes_compound_primary_keys():
|
|||
ds.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_table_data_includes_foreign_key_autocomplete_urls():
|
||||
ds = Datasette([])
|
||||
try:
|
||||
db = ds.add_database(
|
||||
Database(ds, memory_name="test_table_foreign_key_autocomplete"), name="data"
|
||||
)
|
||||
await db.execute_write_script("""
|
||||
create table authors (
|
||||
id integer primary key,
|
||||
name text
|
||||
);
|
||||
create table tags (
|
||||
slug text unique,
|
||||
name text
|
||||
);
|
||||
create table articles (
|
||||
id integer primary key,
|
||||
author_id integer references authors(id),
|
||||
implicit_author_id integer references authors,
|
||||
tag_slug text references tags(slug),
|
||||
title text
|
||||
);
|
||||
insert into authors (id, name) values (1, 'Ada Lovelace');
|
||||
insert into tags (slug, name) values ('science', 'Science');
|
||||
insert into articles (
|
||||
id,
|
||||
author_id,
|
||||
implicit_author_id,
|
||||
tag_slug,
|
||||
title
|
||||
) values (
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
'science',
|
||||
'Notes'
|
||||
);
|
||||
""")
|
||||
response = await ds.client.get("/data/articles")
|
||||
assert response.status_code == 200
|
||||
soup = Soup(response.text, "html.parser")
|
||||
table_data = table_data_from_soup(soup)
|
||||
assert table_data["foreignKeys"] == {
|
||||
"author_id": "/data/authors/-/autocomplete",
|
||||
"implicit_author_id": "/data/authors/-/autocomplete",
|
||||
}
|
||||
assert any(
|
||||
"autocomplete.js" in (script.get("src") or "")
|
||||
for script in soup.find_all("script")
|
||||
)
|
||||
finally:
|
||||
ds.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_table_fragment_endpoint(ds_client):
|
||||
response = await ds_client.get("/fixtures/simple_primary_key/-/fragment?_row=1")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue