diff --git a/datasette/static/edit-tools.js b/datasette/static/edit-tools.js index 74056df5..c8072f8f 100644 --- a/datasette/static/edit-tools.js +++ b/datasette/static/edit-tools.js @@ -822,6 +822,11 @@ function tableCreateSaveButtonText(state) { return "Create table"; } +function tableCreateCanInsertRows() { + var data = databaseCreateTableData() || {}; + return !!data.canInsertRows; +} + function syncTableCreateModeUi(state) { if (!state) { return; @@ -831,7 +836,7 @@ function syncTableCreateModeUi(state) { state.dataPanel.hidden = !isDataMode; state.dataEditor.hidden = !isDataMode || state.dataPreviewReady; state.dataPreview.hidden = !isDataMode || !state.dataPreviewReady; - state.createFromDataLink.hidden = isDataMode; + state.createFromDataLink.hidden = isDataMode || !tableCreateCanInsertRows(); state.manualCreateLink.hidden = !isDataMode; } @@ -1303,7 +1308,7 @@ function resetTableCreateDialog(state) { } function showTableCreateDataMode(state) { - if (!state || state.isSaving) { + if (!state || state.isSaving || !tableCreateCanInsertRows()) { return; } state.mode = "data"; diff --git a/datasette/views/database.py b/datasette/views/database.py index e02de657..c6ea57b8 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -325,7 +325,7 @@ class DatabaseContext(Context): database_color: str = field(metadata={"help": "The color assigned to the database"}) database_page_data: dict = field( metadata={ - "help": 'JSON data used by JavaScript on the database page. Currently ``{}`` or ``{"createTable": {...}}`` where ``createTable`` includes ``path``, ``foreignKeyTargetsPath``, ``databaseName``, ``columnTypes``, ``defaultExpressions`` and optional ``customColumnTypes``.' + "help": 'JSON data used by JavaScript on the database page. Currently ``{}`` or ``{"createTable": {...}}`` where ``createTable`` includes ``path``, ``foreignKeyTargetsPath``, ``databaseName``, ``columnTypes``, ``defaultExpressions``, ``canInsertRows`` and optional ``customColumnTypes``.' } ) database_actions: callable = field( diff --git a/datasette/views/table_create_alter.py b/datasette/views/table_create_alter.py index ffeb7f14..6b3d82d3 100644 --- a/datasette/views/table_create_alter.py +++ b/datasette/views/table_create_alter.py @@ -267,6 +267,11 @@ async def _create_table_ui_context( "databaseName": database_name, "columnTypes": CREATE_TABLE_COLUMN_TYPES, "defaultExpressions": default_expression_options(), + "canInsertRows": await datasette.allowed( + action="insert-row", + resource=DatabaseResource(database=database_name), + actor=request.actor, + ), } can_set_column_type = await datasette.allowed( action="set-column-type", diff --git a/tests/test_table_html.py b/tests/test_table_html.py index be569e68..df1db1a3 100644 --- a/tests/test_table_html.py +++ b/tests/test_table_html.py @@ -1027,6 +1027,7 @@ async def test_database_create_table_action_button_and_data(): "databaseName": "data", "columnTypes": ["text", "integer", "float", "blob"], "defaultExpressions": DEFAULT_EXPRESSION_OPTIONS, + "canInsertRows": False, }, } assert "customColumnTypes" not in database_data_from_soup(soup)["createTable"] @@ -1050,6 +1051,40 @@ async def test_database_create_table_action_button_and_data(): ds.close() +@pytest.mark.asyncio +async def test_database_create_table_data_includes_insert_row_permission(): + ds = Datasette( + [], + config={ + "databases": { + "data": { + "permissions": { + "create-table": {"id": "root"}, + "insert-row": {"id": "root"}, + }, + }, + }, + }, + ) + try: + db = ds.add_database( + Database(ds, memory_name="test_database_create_table_insert_permission"), + name="data", + ) + await db.execute_write_script(""" + create table items (id integer primary key, name text); + """) + + response = await ds.client.get("/data", actor={"id": "root"}) + assert response.status_code == 200 + create_table_data = database_data_from_soup(Soup(response.text, "html.parser"))[ + "createTable" + ] + assert create_table_data["canInsertRows"] is True + finally: + ds.close() + + @pytest.mark.asyncio async def test_database_create_table_data_includes_custom_column_types(): ds = Datasette(