Updating UI to have a table/column deletion check which makes sure the user understands what they are doing, also disabling external table deletion.
This commit is contained in:
parent
95fcaeea06
commit
72bf66926d
|
@ -11,6 +11,7 @@
|
|||
export let readonly = false
|
||||
export let updateOnChange = true
|
||||
export let quiet = false
|
||||
export let dataCy
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let focus = false
|
||||
|
@ -78,6 +79,7 @@
|
|||
{disabled}
|
||||
{readonly}
|
||||
{id}
|
||||
data-cy={dataCy}
|
||||
value={value || ""}
|
||||
placeholder={placeholder || ""}
|
||||
on:click
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
export let error = null
|
||||
export let updateOnChange = true
|
||||
export let quiet = false
|
||||
export let dataCy
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const onChange = e => {
|
||||
|
@ -23,6 +24,7 @@
|
|||
|
||||
<Field {label} {labelPosition} {error}>
|
||||
<TextField
|
||||
{dataCy}
|
||||
{updateOnChange}
|
||||
{error}
|
||||
{disabled}
|
||||
|
|
|
@ -53,6 +53,7 @@ context("Create a Table", () => {
|
|||
cy.get(".spectrum-Table-editIcon > use").click()
|
||||
cy.contains("Delete").click()
|
||||
cy.wait(50)
|
||||
cy.get(`[data-cy="delete-column-confirm"]`).type("nameupdated")
|
||||
cy.contains("Delete Column").click()
|
||||
cy.contains("nameupdated").should("not.exist")
|
||||
})
|
||||
|
@ -66,6 +67,7 @@ context("Create a Table", () => {
|
|||
cy.get(".actions .spectrum-Icon").click({ force: true })
|
||||
})
|
||||
cy.get(".spectrum-Menu > :nth-child(2)").click()
|
||||
cy.get(`[data-cy="delete-table-confirm"]`).type("dog")
|
||||
cy.contains("Delete Table").click()
|
||||
cy.contains("dog").should("not.exist")
|
||||
})
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
let indexes = [...($tables.selected.indexes || [])]
|
||||
let confirmDeleteDialog
|
||||
let deletion
|
||||
let deleteColName
|
||||
|
||||
$: checkConstraints(field)
|
||||
$: required = !!field?.constraints?.presence || primaryDisplay
|
||||
|
@ -408,9 +409,20 @@
|
|||
</ModalContent>
|
||||
<ConfirmDialog
|
||||
bind:this={confirmDeleteDialog}
|
||||
body={`Are you sure you wish to delete this column? Your data will be deleted and this action cannot be undone.`}
|
||||
okText="Delete Column"
|
||||
onOk={deleteColumn}
|
||||
onCancel={hideDeleteDialog}
|
||||
title="Confirm Deletion"
|
||||
/>
|
||||
disabled={deleteColName !== field.name}
|
||||
>
|
||||
<p>
|
||||
Are you sure you wish to delete the column <b>{field.name}?</b>
|
||||
Your data will be deleted and this action cannot be undone - enter the column
|
||||
name to confirm.
|
||||
</p>
|
||||
<Input
|
||||
dataCy="delete-column-confirm"
|
||||
bind:value={deleteColName}
|
||||
placeholder={field.name}
|
||||
/>
|
||||
</ConfirmDialog>
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
let originalName = table.name
|
||||
let templateScreens
|
||||
let willBeDeleted
|
||||
let deleteTableName
|
||||
|
||||
$: external = table?.type === "external"
|
||||
$: allowDeletion = !external || table?.created
|
||||
|
||||
function showDeleteModal() {
|
||||
templateScreens = $allScreens.filter(
|
||||
|
@ -36,15 +38,19 @@
|
|||
|
||||
async function deleteTable() {
|
||||
const wasSelectedTable = $tables.selected
|
||||
await tables.delete(table)
|
||||
store.actions.screens.delete(templateScreens)
|
||||
await tables.fetch()
|
||||
notifications.success("Table deleted")
|
||||
if (table.type === "external") {
|
||||
await datasources.fetch()
|
||||
}
|
||||
if (wasSelectedTable && wasSelectedTable._id === table._id) {
|
||||
$goto("./table")
|
||||
try {
|
||||
await tables.delete(table)
|
||||
await store.actions.screens.delete(templateScreens)
|
||||
await tables.fetch()
|
||||
if (table.type === "external") {
|
||||
await datasources.fetch()
|
||||
}
|
||||
notifications.success("Table deleted")
|
||||
if (wasSelectedTable && wasSelectedTable._id === table._id) {
|
||||
$goto("./table")
|
||||
}
|
||||
} catch (err) {
|
||||
notifications.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +73,9 @@
|
|||
<Icon s hoverable name="MoreSmallList" />
|
||||
</div>
|
||||
<MenuItem icon="Edit" on:click={editorModal.show}>Edit</MenuItem>
|
||||
<MenuItem icon="Delete" on:click={showDeleteModal}>Delete</MenuItem>
|
||||
{#if allowDeletion}
|
||||
<MenuItem icon="Delete" on:click={showDeleteModal}>Delete</MenuItem>
|
||||
{/if}
|
||||
</ActionMenu>
|
||||
|
||||
<Modal bind:this={editorModal}>
|
||||
|
@ -91,10 +99,13 @@
|
|||
okText="Delete Table"
|
||||
onOk={deleteTable}
|
||||
title="Confirm Deletion"
|
||||
disabled={deleteTableName !== table.name}
|
||||
>
|
||||
Are you sure you wish to delete the table
|
||||
<i>{table.name}?</i>
|
||||
The following will also be deleted:
|
||||
<p>
|
||||
Are you sure you wish to delete the table
|
||||
<b>{table.name}?</b>
|
||||
The following will also be deleted:
|
||||
</p>
|
||||
<b>
|
||||
<div class="delete-items">
|
||||
{#each willBeDeleted as item}
|
||||
|
@ -102,7 +113,15 @@
|
|||
{/each}
|
||||
</div>
|
||||
</b>
|
||||
This action cannot be undone.
|
||||
<p>
|
||||
This action cannot be undone - to continue please enter the table name below
|
||||
to confirm.
|
||||
</p>
|
||||
<Input
|
||||
bind:value={deleteTableName}
|
||||
placeholder={table.name}
|
||||
dataCy="delete-table-confirm"
|
||||
/>
|
||||
</ConfirmDialog>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -305,7 +305,11 @@
|
|||
Are you sure you want to delete the app <b>{selectedApp?.name}</b>?
|
||||
|
||||
<p>Please enter the app name below to confirm.</p>
|
||||
<Input bind:value={appName} data-cy="delete-app-confirmation" />
|
||||
<Input
|
||||
bind:value={appName}
|
||||
data-cy="delete-app-confirmation"
|
||||
placeholder={selectedApp?.name}
|
||||
/>
|
||||
</ConfirmDialog>
|
||||
<ConfirmDialog
|
||||
bind:this={unpublishModal}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { writable, get } from "svelte/store"
|
||||
import { views, queries, datasources } from "./"
|
||||
import { get, writable } from "svelte/store"
|
||||
import { datasources, queries, views } from "./"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import api from "builderStore/api"
|
||||
import { SWITCHABLE_TYPES } from "../../constants/backend"
|
||||
|
@ -97,7 +97,12 @@ export function createTablesStore() {
|
|||
})
|
||||
},
|
||||
delete: async table => {
|
||||
await api.delete(`/api/tables/${table._id}/${table._rev}`)
|
||||
const response = await api.delete(
|
||||
`/api/tables/${table._id}/${table._rev}`
|
||||
)
|
||||
if (response.status !== 200) {
|
||||
throw (await response.json()).message
|
||||
}
|
||||
update(state => ({
|
||||
...state,
|
||||
list: state.list.filter(existing => existing._id !== table._id),
|
||||
|
|
|
@ -161,9 +161,13 @@ function isRelationshipSetup(column) {
|
|||
exports.save = async function (ctx) {
|
||||
const appId = ctx.appId
|
||||
const table = ctx.request.body
|
||||
// can't do this
|
||||
// can't do this right now
|
||||
delete table.dataImport
|
||||
const datasourceId = getDatasourceId(ctx.request.body)
|
||||
// table doesn't exist already, note that it is created
|
||||
if (!table._id) {
|
||||
table.created = true
|
||||
}
|
||||
let tableToSave = {
|
||||
type: "table",
|
||||
_id: buildExternalTableId(datasourceId, table.name),
|
||||
|
@ -265,6 +269,9 @@ exports.save = async function (ctx) {
|
|||
exports.destroy = async function (ctx) {
|
||||
const appId = ctx.appId
|
||||
const tableToDelete = await getTable(appId, ctx.params.tableId)
|
||||
if (!tableToDelete || !tableToDelete.created) {
|
||||
ctx.throw(400, "Cannot delete tables which weren't created in Budibase.")
|
||||
}
|
||||
const datasourceId = getDatasourceId(tableToDelete)
|
||||
|
||||
const db = new CouchDB(appId)
|
||||
|
|
Loading…
Reference in New Issue