TS conversions of components required to create generic deletion component.

This commit is contained in:
mike12345567 2025-01-29 16:58:49 +00:00
parent 8fe277e584
commit 6b566d8b7a
7 changed files with 193 additions and 25 deletions

View File

@ -1,8 +1,9 @@
<script>
<script lang="ts">
import "@spectrum-css/textfield/dist/index-vars.css"
import { createEventDispatcher, onMount, tick } from "svelte"
import type { UIEvent } from "@budibase/types"
export let value = null
export let value: string | null = null
export let placeholder = null
export let type = "text"
export let disabled = false
@ -10,21 +11,21 @@
export let readonly = false
export let updateOnChange = true
export let quiet = false
export let align
export let align: string | null = null
export let autofocus = false
export let autocomplete = null
const dispatch = createEventDispatcher()
let field
let field: any
let focus = false
const updateValue = newValue => {
const updateValue = (newValue: string | number | null) => {
if (readonly || disabled) {
return
}
if (type === "number") {
const float = parseFloat(newValue)
const float = parseFloat(newValue as string)
newValue = isNaN(float) ? null : float
}
dispatch("change", newValue)
@ -37,31 +38,31 @@
focus = true
}
const onBlur = event => {
const onBlur = (event: UIEvent) => {
if (readonly || disabled) {
return
}
focus = false
updateValue(event.target.value)
updateValue(event?.target?.value)
}
const onInput = event => {
const onInput = (event: UIEvent) => {
if (readonly || !updateOnChange || disabled) {
return
}
updateValue(event.target.value)
updateValue(event.target?.value)
}
const updateValueOnEnter = event => {
const updateValueOnEnter = (event: UIEvent) => {
if (readonly || disabled) {
return
}
if (event.key === "Enter") {
updateValue(event.target.value)
updateValue(event.target?.value)
}
}
const getInputMode = type => {
const getInputMode = (type: string) => {
if (type === "bigint") {
return "numeric"
}

View File

@ -1,13 +1,13 @@
<script>
<script lang="ts">
import "@spectrum-css/fieldlabel/dist/index-vars.css"
import FieldLabel from "./FieldLabel.svelte"
import Icon from "../Icon/Icon.svelte"
export let id = null
export let label = null
export let id: string | null = null
export let label: string | null = null
export let labelPosition = "above"
export let error = null
export let helpText = null
export let error: string | null = null
export let helpText: string | null = null
export let tooltip = ""
</script>

View File

@ -1,12 +1,12 @@
<script>
<script lang="ts">
import Field from "./Field.svelte"
import TextField from "./Core/TextField.svelte"
import { createEventDispatcher } from "svelte"
export let value = null
export let label = null
export let value: string | null = null
export let label: string | null = null
export let labelPosition = "above"
export let placeholder = null
export let placeholder: string | null = null
export let type = "text"
export let disabled = false
export let readonly = false
@ -18,7 +18,7 @@
export let helpText = null
const dispatch = createEventDispatcher()
const onChange = e => {
const onChange = (e: any) => {
value = e.detail
dispatch("change", e.detail)
}
@ -27,7 +27,6 @@
<Field {helpText} {label} {labelPosition} {error}>
<TextField
{updateOnChange}
{error}
{disabled}
{readonly}
{value}

View File

@ -10,7 +10,7 @@
export let secondary = false
export let overBackground = false
export let target
export let download
export let download = null
export let disabled = false
export let tooltip = null

View File

@ -0,0 +1,164 @@
<script lang="ts">
import { InlineAlert, Link, Input } from "@budibase/bbui"
import { appStore } from "@/stores/builder"
import ConfirmDialog from "@/components/common/ConfirmDialog.svelte"
import type { Table, View, Datasource, Query } from "@budibase/types"
export let source: Table | View | Datasource | Query | undefined
export let deleteSourceFn: () => Promise<void>
let confirmDeleteDialog: any
let affectedScreens: { text: string; url: string }[] = []
let viewsMessage: string = ""
let deleteSourceName: string | undefined
const getViewsMessage = () => {
if (!source || !("views" in source)) {
return ""
}
const views = Object.values(source?.views ?? [])
if (views.length < 1) {
return ""
}
if (views.length === 1) {
return ", including 1 view"
}
return `, including ${views.length} views`
}
export const show = () => {
viewsMessage = getViewsMessage()
// TODO: fetch information about screens affected
confirmDeleteDialog.show()
}
function processScreens(
screens: { url: string; _id: string }[]
): { text: string; url: string }[] {
return screens.map(({ url, _id }) => ({
text: url,
url: `/builder/app/${$appStore.appId}/design/${_id}`,
}))
}
function hideDeleteDialog() {
deleteSourceName = ""
}
const autofillSourceName = () => {
deleteSourceName = source?.name
}
</script>
<ConfirmDialog
bind:this={confirmDeleteDialog}
okText="Delete Table"
onOk={deleteSourceFn}
onCancel={hideDeleteDialog}
title="Confirm Deletion"
disabled={deleteSourceName !== source?.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={autofillSourceName} class="sourceName">{source?.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 affectedScreens.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 affectedScreens 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 "<b><i>{source?.name}</i></b>" below to confirm.
</p>
<Input bind:value={deleteSourceName} placeholder={source?.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;
}
.sourceName {
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>

View File

@ -0,0 +1,3 @@
export type UIEvent = Event & {
currentTarget: EventTarget & HTMLInputElement
} & { key?: string } & { target?: any }

View File

@ -3,3 +3,4 @@ export * from "./bindings"
export * from "./components"
export * from "./dataFetch"
export * from "./datasource"
export * from "./common"