Getting tables and views to be deleted through the new generic modal.
This commit is contained in:
parent
a1409f43fa
commit
be33f59ff0
|
@ -1,175 +0,0 @@
|
||||||
<script>
|
|
||||||
import { goto, params } from "@roxi/routify"
|
|
||||||
import { appStore, tables, datasources, screenStore } from "@/stores/builder"
|
|
||||||
import { InlineAlert, Link, Input, notifications } from "@budibase/bbui"
|
|
||||||
import ConfirmDialog from "@/components/common/ConfirmDialog.svelte"
|
|
||||||
import { DB_TYPE_EXTERNAL } from "@/constants/backend"
|
|
||||||
|
|
||||||
export let table
|
|
||||||
|
|
||||||
let confirmDeleteDialog
|
|
||||||
|
|
||||||
let screensPossiblyAffected = []
|
|
||||||
let viewsMessage = ""
|
|
||||||
let deleteTableName
|
|
||||||
|
|
||||||
const getViewsMessage = () => {
|
|
||||||
const views = Object.values(table?.views ?? [])
|
|
||||||
if (views.length < 1) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if (views.length === 1) {
|
|
||||||
return ", including 1 view"
|
|
||||||
}
|
|
||||||
|
|
||||||
return `, including ${views.length} views`
|
|
||||||
}
|
|
||||||
|
|
||||||
export const show = () => {
|
|
||||||
viewsMessage = getViewsMessage()
|
|
||||||
screensPossiblyAffected = $screenStore.screens
|
|
||||||
.filter(
|
|
||||||
screen => screen.autoTableId === table._id && screen.routing?.route
|
|
||||||
)
|
|
||||||
.map(screen => ({
|
|
||||||
text: screen.routing.route,
|
|
||||||
url: `/builder/app/${$appStore.appId}/design/${screen._id}`,
|
|
||||||
}))
|
|
||||||
|
|
||||||
confirmDeleteDialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteTable() {
|
|
||||||
const isSelected = $params.tableId === table._id
|
|
||||||
try {
|
|
||||||
await tables.delete(table)
|
|
||||||
|
|
||||||
if (table.sourceType === DB_TYPE_EXTERNAL) {
|
|
||||||
await datasources.fetch()
|
|
||||||
}
|
|
||||||
notifications.success("Table deleted")
|
|
||||||
if (isSelected) {
|
|
||||||
$goto(`./datasource/${table.datasourceId}`)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
notifications.error(`Error deleting table - ${error.message}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideDeleteDialog() {
|
|
||||||
deleteTableName = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const autofillTableName = () => {
|
|
||||||
deleteTableName = table.name
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ConfirmDialog
|
|
||||||
bind:this={confirmDeleteDialog}
|
|
||||||
okText="Delete Table"
|
|
||||||
onOk={deleteTable}
|
|
||||||
onCancel={hideDeleteDialog}
|
|
||||||
title="Confirm Deletion"
|
|
||||||
disabled={deleteTableName !== table.name}
|
|
||||||
>
|
|
||||||
<div class="content">
|
|
||||||
<p class="firstWarning">
|
|
||||||
Are you sure you wish to delete the table
|
|
||||||
<span class="tableNameLine">
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
||||||
<b on:click={autofillTableName} class="tableName">{table.name}</b>
|
|
||||||
<span>?</span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="secondWarning">All table data will be deleted{viewsMessage}.</p>
|
|
||||||
<p class="thirdWarning">This action <b>cannot be undone</b>.</p>
|
|
||||||
|
|
||||||
{#if screensPossiblyAffected.length > 0}
|
|
||||||
<div class="affectedScreens">
|
|
||||||
<InlineAlert
|
|
||||||
header="The following screens were originally generated from this table and may no longer function as expected"
|
|
||||||
>
|
|
||||||
<ul class="affectedScreensList">
|
|
||||||
{#each screensPossiblyAffected as item}
|
|
||||||
<li>
|
|
||||||
<Link quiet overBackground target="_blank" href={item.url}
|
|
||||||
>{item.text}</Link
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
</InlineAlert>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<p class="fourthWarning">Please enter the table name below to confirm.</p>
|
|
||||||
<Input bind:value={deleteTableName} placeholder={table.name} />
|
|
||||||
</div>
|
|
||||||
</ConfirmDialog>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.content {
|
|
||||||
margin-top: 0;
|
|
||||||
max-width: 320px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firstWarning {
|
|
||||||
margin: 0 0 12px;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tableNameLine {
|
|
||||||
display: inline-flex;
|
|
||||||
max-width: 100%;
|
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tableName {
|
|
||||||
flex-grow: 1;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondWarning {
|
|
||||||
margin: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thirdWarning {
|
|
||||||
margin: 0 0 12px;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.affectedScreens {
|
|
||||||
margin: 18px 0;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.affectedScreens :global(.spectrum-InLineAlert) {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.affectedScreensList {
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.affectedScreensList li {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fourthWarning {
|
|
||||||
margin: 12px 0 6px;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -8,7 +8,7 @@
|
||||||
import NavItem from "@/components/common/NavItem.svelte"
|
import NavItem from "@/components/common/NavItem.svelte"
|
||||||
import { isActive } from "@roxi/routify"
|
import { isActive } from "@roxi/routify"
|
||||||
import EditModal from "./EditModal.svelte"
|
import EditModal from "./EditModal.svelte"
|
||||||
import DeleteConfirmationModal from "./DeleteConfirmationModal.svelte"
|
import DeleteConfirmationModal from "../../modals/DeleteDataConfirmationModal.svelte"
|
||||||
import { Icon } from "@budibase/bbui"
|
import { Icon } from "@budibase/bbui"
|
||||||
import { DB_TYPE_EXTERNAL } from "@/constants/backend"
|
import { DB_TYPE_EXTERNAL } from "@/constants/backend"
|
||||||
|
|
||||||
|
@ -65,4 +65,4 @@
|
||||||
{/if}
|
{/if}
|
||||||
</NavItem>
|
</NavItem>
|
||||||
<EditModal {table} bind:this={editModal} />
|
<EditModal {table} bind:this={editModal} />
|
||||||
<DeleteConfirmationModal {table} bind:this={deleteConfirmationModal} />
|
<DeleteConfirmationModal source={table} bind:this={deleteConfirmationModal} />
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { InlineAlert, Link, Input } from "@budibase/bbui"
|
import { InlineAlert, Link, Input, notifications } from "@budibase/bbui"
|
||||||
import { appStore, screenStore } from "@/stores/builder"
|
import {
|
||||||
|
appStore,
|
||||||
|
datasources,
|
||||||
|
screenStore,
|
||||||
|
tables,
|
||||||
|
views,
|
||||||
|
viewsV2,
|
||||||
|
} from "@/stores/builder"
|
||||||
import ConfirmDialog from "@/components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "@/components/common/ConfirmDialog.svelte"
|
||||||
import type { Table, ViewV2, Datasource, Query } from "@budibase/types"
|
import { SourceType } from "@budibase/types"
|
||||||
|
import { goto, params } from "@roxi/routify"
|
||||||
|
import { DB_TYPE_EXTERNAL } from "@/constants/backend"
|
||||||
|
import type { Table, ViewV2, View, Datasource, Query } from "@budibase/types"
|
||||||
|
|
||||||
export let source: Table | ViewV2 | Datasource | Query | undefined
|
export let source: Table | ViewV2 | Datasource | Query | undefined
|
||||||
export let type: "table" | "view" | "datasource" | "query"
|
|
||||||
export let deleteSourceFn: () => Promise<void>
|
|
||||||
|
|
||||||
let confirmDeleteDialog: any
|
let confirmDeleteDialog: any
|
||||||
let affectedScreens: { text: string; url: string }[] = []
|
let affectedScreens: { text: string; url: string }[] = []
|
||||||
|
let sourceType: SourceType | undefined = undefined
|
||||||
let viewsMessage: string = ""
|
let viewsMessage: string = ""
|
||||||
let deleteSourceName: string | undefined
|
let deleteSourceName: string | undefined
|
||||||
|
|
||||||
|
@ -43,6 +51,7 @@
|
||||||
viewsMessage = getViewsMessage()
|
viewsMessage = getViewsMessage()
|
||||||
const usage = await screenStore.usageOfScreens(getSourceID())
|
const usage = await screenStore.usageOfScreens(getSourceID())
|
||||||
affectedScreens = processScreens(usage.screens)
|
affectedScreens = processScreens(usage.screens)
|
||||||
|
sourceType = usage.sourceType
|
||||||
confirmDeleteDialog.show()
|
confirmDeleteDialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,19 +71,68 @@
|
||||||
const autofillSourceName = () => {
|
const autofillSourceName = () => {
|
||||||
deleteSourceName = source?.name
|
deleteSourceName = source?.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deleteTable(table: Table & { datasourceId?: string }) {
|
||||||
|
const isSelected = $params.tableId === table._id
|
||||||
|
try {
|
||||||
|
await tables.delete({
|
||||||
|
_id: table._id!,
|
||||||
|
_rev: table._rev!,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (table.sourceType === DB_TYPE_EXTERNAL) {
|
||||||
|
await datasources.fetch()
|
||||||
|
}
|
||||||
|
notifications.success("Table deleted")
|
||||||
|
if (isSelected) {
|
||||||
|
$goto(`./datasource/${table.datasourceId}`)
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
notifications.error(`Error deleting table - ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteView(view: ViewV2 | View) {
|
||||||
|
try {
|
||||||
|
if ("version" in view && view.version === 2) {
|
||||||
|
await viewsV2.delete(view as ViewV2)
|
||||||
|
} else {
|
||||||
|
await views.delete(view as View)
|
||||||
|
}
|
||||||
|
notifications.success("View deleted")
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
notifications.error("Error deleting view")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteSource() {
|
||||||
|
if (!source || !sourceType) {
|
||||||
|
throw new Error("Unable to delete - no data source found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sourceType) {
|
||||||
|
case SourceType.TABLE:
|
||||||
|
return await deleteTable(source as Table)
|
||||||
|
case SourceType.VIEW:
|
||||||
|
return await deleteView(source as ViewV2)
|
||||||
|
case SourceType.DATASOURCE:
|
||||||
|
case SourceType.QUERY:
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:this={confirmDeleteDialog}
|
bind:this={confirmDeleteDialog}
|
||||||
okText={`Delete ${type}`}
|
okText={`Delete ${sourceType}`}
|
||||||
onOk={deleteSourceFn}
|
onOk={deleteSource}
|
||||||
onCancel={hideDeleteDialog}
|
onCancel={hideDeleteDialog}
|
||||||
title="Confirm Deletion"
|
title="Confirm Deletion"
|
||||||
disabled={deleteSourceName !== source?.name}
|
disabled={deleteSourceName !== source?.name}
|
||||||
>
|
>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p class="firstWarning">
|
<p class="firstWarning">
|
||||||
Are you sure you wish to delete the {type}
|
Are you sure you wish to delete the {sourceType}
|
||||||
<span class="sourceNameLine">
|
<span class="sourceNameLine">
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
|
@ -83,13 +141,15 @@
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="secondWarning">All {type} data will be deleted{viewsMessage}.</p>
|
<p class="secondWarning">
|
||||||
|
All {sourceType} data will be deleted{viewsMessage}.
|
||||||
|
</p>
|
||||||
<p class="thirdWarning">This action <b>cannot be undone</b>.</p>
|
<p class="thirdWarning">This action <b>cannot be undone</b>.</p>
|
||||||
|
|
||||||
{#if affectedScreens.length > 0}
|
{#if affectedScreens.length > 0}
|
||||||
<div class="affectedScreens">
|
<div class="affectedScreens">
|
||||||
<InlineAlert
|
<InlineAlert
|
||||||
header={`The following screens were originally generated from this ${type} and may no longer function as expected`}
|
header={`The following screens use this ${sourceType} and may no longer function as expected`}
|
||||||
>
|
>
|
||||||
<ul class="affectedScreensList">
|
<ul class="affectedScreensList">
|
||||||
{#each affectedScreens as item}
|
{#each affectedScreens as item}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
<script>
|
|
||||||
import { views, viewsV2 } from "@/stores/builder"
|
|
||||||
import ConfirmDialog from "@/components/common/ConfirmDialog.svelte"
|
|
||||||
import { notifications } from "@budibase/bbui"
|
|
||||||
|
|
||||||
export let view
|
|
||||||
|
|
||||||
let confirmDeleteDialog
|
|
||||||
|
|
||||||
export const show = () => {
|
|
||||||
confirmDeleteDialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteView() {
|
|
||||||
try {
|
|
||||||
if (view.version === 2) {
|
|
||||||
await viewsV2.delete(view)
|
|
||||||
} else {
|
|
||||||
await views.delete(view)
|
|
||||||
}
|
|
||||||
notifications.success("View deleted")
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
notifications.error("Error deleting view")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ConfirmDialog
|
|
||||||
bind:this={confirmDeleteDialog}
|
|
||||||
body={`Are you sure you wish to delete the view '${view.name}'? Your data will be deleted and this action cannot be undone.`}
|
|
||||||
okText="Delete View"
|
|
||||||
onOk={deleteView}
|
|
||||||
title="Confirm Deletion"
|
|
||||||
/>
|
|
|
@ -10,9 +10,8 @@
|
||||||
import { Icon, ActionButton, ActionMenu, MenuItem } from "@budibase/bbui"
|
import { Icon, ActionButton, ActionMenu, MenuItem } from "@budibase/bbui"
|
||||||
import { params, url } from "@roxi/routify"
|
import { params, url } from "@roxi/routify"
|
||||||
import EditViewModal from "./EditViewModal.svelte"
|
import EditViewModal from "./EditViewModal.svelte"
|
||||||
import DeleteViewModal from "./DeleteViewModal.svelte"
|
|
||||||
import EditTableModal from "@/components/backend/TableNavigator/TableNavItem/EditModal.svelte"
|
import EditTableModal from "@/components/backend/TableNavigator/TableNavItem/EditModal.svelte"
|
||||||
import DeleteTableModal from "@/components/backend/TableNavigator/TableNavItem/DeleteConfirmationModal.svelte"
|
import DeleteConfirmationModal from "@/components/backend/modals/DeleteDataConfirmationModal.svelte"
|
||||||
import { UserAvatars } from "@budibase/frontend-core"
|
import { UserAvatars } from "@budibase/frontend-core"
|
||||||
import { DB_TYPE_EXTERNAL } from "@/constants/backend"
|
import { DB_TYPE_EXTERNAL } from "@/constants/backend"
|
||||||
import { TableNames } from "@/constants"
|
import { TableNames } from "@/constants"
|
||||||
|
@ -314,12 +313,12 @@
|
||||||
|
|
||||||
{#if table && tableEditable}
|
{#if table && tableEditable}
|
||||||
<EditTableModal {table} bind:this={editTableModal} />
|
<EditTableModal {table} bind:this={editTableModal} />
|
||||||
<DeleteTableModal {table} bind:this={deleteTableModal} />
|
<DeleteConfirmationModal source={table} bind:this={deleteTableModal} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if editableView}
|
{#if editableView}
|
||||||
<EditViewModal view={editableView} bind:this={editViewModal} />
|
<EditViewModal view={editableView} bind:this={editViewModal} />
|
||||||
<DeleteViewModal view={editableView} bind:this={deleteViewModal} />
|
<DeleteConfirmationModal source={editableView} bind:this={deleteViewModal} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
Loading…
Reference in New Issue