diff --git a/datasette/static/app.css b/datasette/static/app.css index 06919444..1cca8b80 100644 --- a/datasette/static/app.css +++ b/datasette/static/app.css @@ -2542,6 +2542,22 @@ dialog.table-alter-dialog::backdrop { color: var(--ink); } +.table-alter-dialog .btn-danger { + background: #b91c1c; + color: #fff; + margin-right: auto; +} + +.table-alter-dialog .btn-danger:hover { + background: #991b1b; +} + +.table-alter-dialog .btn-danger:disabled, +.table-alter-dialog .btn-danger:disabled:hover { + background: #d98c8c; + color: #fff; +} + .table-alter-dialog .btn-primary { background: var(--accent); color: #fff; diff --git a/datasette/static/edit-tools.js b/datasette/static/edit-tools.js index 2a0a29b2..779ec702 100644 --- a/datasette/static/edit-tools.js +++ b/datasette/static/edit-tools.js @@ -1571,6 +1571,7 @@ function setTableAlterDialogSaving(state, isSaving) { state.cancelButton.disabled = isSaving; state.addColumnButton.disabled = isSaving; state.backButton.disabled = isSaving; + state.dropButton.disabled = isSaving; state.saveButton.textContent = isSaving ? state.mode === "review" ? "Applying..." @@ -2465,6 +2466,8 @@ function showTableAlterEditor(state) { state.review.hidden = true; state.review.textContent = ""; state.backButton.hidden = true; + var data = tableAlterData(); + state.dropButton.hidden = !(data && data.dropPath); state.saveButton.textContent = tableAlterSaveButtonText(state); updateTableAlterMoveButtons(state); updateTableAlterSaveButtonState(state); @@ -2479,6 +2482,7 @@ function showTableAlterReview(state, result) { state.review.hidden = false; state.review.textContent = ""; state.backButton.hidden = false; + state.dropButton.hidden = true; state.saveButton.textContent = tableAlterSaveButtonText(state); updateTableAlterSaveButtonState(state); @@ -2565,6 +2569,64 @@ async function applyTableAlterChanges(state, result) { } } +function tableAlterDatabaseUrl() { + var data = tableAlterData(); + if (!data || !data.path) { + return null; + } + var url = new URL(data.path, location.href); + url.pathname = url.pathname.replace(/\/[^/]+\/-\/alter\/?$/, ""); + url.search = ""; + url.hash = ""; + return url.toString(); +} + +async function dropTableFromAlterDialog(state) { + if (state.isSaving) { + return; + } + var data = tableAlterData(); + if (!data || !data.dropPath) { + return; + } + if ( + !window.confirm( + 'Permanently delete the table "' + + data.tableName + + '"? This will delete all of its data and cannot be undone.', + ) + ) { + return; + } + clearTableAlterDialogError(state); + setTableAlterDialogSaving(state, true); + try { + var response = await fetch(data.dropPath, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify({ confirm: true }), + }); + var responseData = null; + try { + responseData = await response.json(); + } catch (_error) { + responseData = null; + } + if (!response.ok || (responseData && responseData.ok === false)) { + throw rowMutationRequestError(response, responseData); + } + state.shouldRestoreFocus = false; + state.dialog.close(); + window.location.href = tableAlterDatabaseUrl() || "/"; + } catch (error) { + setTableAlterDialogSaving(state, false); + showTableAlterDialogError(state, error.message || "Could not drop table"); + } +} + async function saveTableAlterDialog(state) { if (state.isSaving) { return; @@ -2646,6 +2708,7 @@ function ensureTableAlterDialog(manager) {