TS conversions of components required to create generic deletion component.
This commit is contained in:
parent
8fe277e584
commit
6b566d8b7a
|
@ -1,8 +1,9 @@
|
||||||
<script>
|
<script lang="ts">
|
||||||
import "@spectrum-css/textfield/dist/index-vars.css"
|
import "@spectrum-css/textfield/dist/index-vars.css"
|
||||||
import { createEventDispatcher, onMount, tick } from "svelte"
|
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 placeholder = null
|
||||||
export let type = "text"
|
export let type = "text"
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
@ -10,21 +11,21 @@
|
||||||
export let readonly = false
|
export let readonly = false
|
||||||
export let updateOnChange = true
|
export let updateOnChange = true
|
||||||
export let quiet = false
|
export let quiet = false
|
||||||
export let align
|
export let align: string | null = null
|
||||||
export let autofocus = false
|
export let autofocus = false
|
||||||
export let autocomplete = null
|
export let autocomplete = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let field
|
let field: any
|
||||||
let focus = false
|
let focus = false
|
||||||
|
|
||||||
const updateValue = newValue => {
|
const updateValue = (newValue: string | number | null) => {
|
||||||
if (readonly || disabled) {
|
if (readonly || disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (type === "number") {
|
if (type === "number") {
|
||||||
const float = parseFloat(newValue)
|
const float = parseFloat(newValue as string)
|
||||||
newValue = isNaN(float) ? null : float
|
newValue = isNaN(float) ? null : float
|
||||||
}
|
}
|
||||||
dispatch("change", newValue)
|
dispatch("change", newValue)
|
||||||
|
@ -37,31 +38,31 @@
|
||||||
focus = true
|
focus = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBlur = event => {
|
const onBlur = (event: UIEvent) => {
|
||||||
if (readonly || disabled) {
|
if (readonly || disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
focus = false
|
focus = false
|
||||||
updateValue(event.target.value)
|
updateValue(event?.target?.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onInput = event => {
|
const onInput = (event: UIEvent) => {
|
||||||
if (readonly || !updateOnChange || disabled) {
|
if (readonly || !updateOnChange || disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updateValue(event.target.value)
|
updateValue(event.target?.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValueOnEnter = event => {
|
const updateValueOnEnter = (event: UIEvent) => {
|
||||||
if (readonly || disabled) {
|
if (readonly || disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
updateValue(event.target.value)
|
updateValue(event.target?.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getInputMode = type => {
|
const getInputMode = (type: string) => {
|
||||||
if (type === "bigint") {
|
if (type === "bigint") {
|
||||||
return "numeric"
|
return "numeric"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<script>
|
<script lang="ts">
|
||||||
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
||||||
import FieldLabel from "./FieldLabel.svelte"
|
import FieldLabel from "./FieldLabel.svelte"
|
||||||
import Icon from "../Icon/Icon.svelte"
|
import Icon from "../Icon/Icon.svelte"
|
||||||
|
|
||||||
export let id = null
|
export let id: string | null = null
|
||||||
export let label = null
|
export let label: string | null = null
|
||||||
export let labelPosition = "above"
|
export let labelPosition = "above"
|
||||||
export let error = null
|
export let error: string | null = null
|
||||||
export let helpText = null
|
export let helpText: string | null = null
|
||||||
export let tooltip = ""
|
export let tooltip = ""
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<script>
|
<script lang="ts">
|
||||||
import Field from "./Field.svelte"
|
import Field from "./Field.svelte"
|
||||||
import TextField from "./Core/TextField.svelte"
|
import TextField from "./Core/TextField.svelte"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
export let value = null
|
export let value: string | null = null
|
||||||
export let label = null
|
export let label: string | null = null
|
||||||
export let labelPosition = "above"
|
export let labelPosition = "above"
|
||||||
export let placeholder = null
|
export let placeholder: string | null = null
|
||||||
export let type = "text"
|
export let type = "text"
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let readonly = false
|
export let readonly = false
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
export let helpText = null
|
export let helpText = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const onChange = e => {
|
const onChange = (e: any) => {
|
||||||
value = e.detail
|
value = e.detail
|
||||||
dispatch("change", e.detail)
|
dispatch("change", e.detail)
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
<Field {helpText} {label} {labelPosition} {error}>
|
<Field {helpText} {label} {labelPosition} {error}>
|
||||||
<TextField
|
<TextField
|
||||||
{updateOnChange}
|
{updateOnChange}
|
||||||
{error}
|
|
||||||
{disabled}
|
{disabled}
|
||||||
{readonly}
|
{readonly}
|
||||||
{value}
|
{value}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
export let secondary = false
|
export let secondary = false
|
||||||
export let overBackground = false
|
export let overBackground = false
|
||||||
export let target
|
export let target
|
||||||
export let download
|
export let download = null
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let tooltip = null
|
export let tooltip = null
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -0,0 +1,3 @@
|
||||||
|
export type UIEvent = Event & {
|
||||||
|
currentTarget: EventTarget & HTMLInputElement
|
||||||
|
} & { key?: string } & { target?: any }
|
|
@ -3,3 +3,4 @@ export * from "./bindings"
|
||||||
export * from "./components"
|
export * from "./components"
|
||||||
export * from "./dataFetch"
|
export * from "./dataFetch"
|
||||||
export * from "./datasource"
|
export * from "./datasource"
|
||||||
|
export * from "./common"
|
||||||
|
|
Loading…
Reference in New Issue