fix(apps): improve app table actionButtons behavior under many clicks
This commit is contained in:
@@ -49,9 +49,6 @@
|
||||
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
|
||||
let beforeIconComponent: any
|
||||
let afterIconComponent: any
|
||||
|
||||
@@ -72,21 +69,6 @@
|
||||
|
||||
$: resolvedConfig?.triggerOnAppLoad && runnableComponent?.runComponent()
|
||||
|
||||
$: if (outputs?.loading != undefined) {
|
||||
outputs.loading.set(false, true)
|
||||
}
|
||||
|
||||
$: outputs?.loading.subscribe({
|
||||
id: 'loading-' + id,
|
||||
next: (value) => {
|
||||
isLoading = value
|
||||
if (ownClick && !value) {
|
||||
ownClick = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$: loading = isLoading && ownClick
|
||||
let errors: Record<string, string> = {}
|
||||
$: errorsMessage = Object.values(errors)
|
||||
.filter((x) => x != '')
|
||||
@@ -103,14 +85,13 @@
|
||||
await preclickAction()
|
||||
}
|
||||
|
||||
ownClick = true
|
||||
|
||||
if (!runnableComponent) {
|
||||
runnableWrapper.onSuccess()
|
||||
} else {
|
||||
await runnableComponent?.runComponent()
|
||||
}
|
||||
}
|
||||
let loading = false
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['buttoncomponent'].initialData.configuration) as key (key)}
|
||||
@@ -129,6 +110,7 @@
|
||||
bind:this={runnableWrapper}
|
||||
{recomputeIds}
|
||||
bind:runnableComponent
|
||||
bind:loading
|
||||
{componentInput}
|
||||
doOnSuccess={resolvedConfig.onSuccess}
|
||||
{id}
|
||||
|
||||
@@ -43,18 +43,9 @@
|
||||
$stateId != undefined &&
|
||||
(componentInput?.type != 'runnable' || Object.keys(componentInput?.fields ?? {}).length == 0)
|
||||
|
||||
$: if (outputs?.loading != undefined) {
|
||||
outputs.loading.set(false, true)
|
||||
}
|
||||
|
||||
$: outputs?.loading.subscribe({
|
||||
id: 'loading-' + id,
|
||||
next: (value) => {
|
||||
isLoading = value
|
||||
}
|
||||
})
|
||||
|
||||
$: css = concatCustomCss($app.css?.formcomponent, customCss)
|
||||
|
||||
let loading = false
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['formcomponent'].initialData.configuration) as key (key)}
|
||||
@@ -70,6 +61,7 @@
|
||||
{recomputeIds}
|
||||
{render}
|
||||
bind:runnableComponent
|
||||
bind:loading
|
||||
{componentInput}
|
||||
{id}
|
||||
doOnSuccess={resolvedConfig.onSuccess}
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
)
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
let errors: Record<string, string> = {}
|
||||
|
||||
$: errorsMessage = Object.values(errors)
|
||||
@@ -55,20 +53,9 @@
|
||||
outputs.loading.set(false, true)
|
||||
}
|
||||
|
||||
$: outputs?.loading.subscribe({
|
||||
id: 'loading-' + id,
|
||||
next: (value) => {
|
||||
isLoading = value
|
||||
if (ownClick && !value) {
|
||||
ownClick = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$: loading = isLoading && ownClick
|
||||
|
||||
$: css = concatCustomCss($app?.css?.formbuttoncomponent, customCss)
|
||||
let runnableWrapper: RunnableWrapper
|
||||
let loading = false
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['formbuttoncomponent'].initialData.configuration) as key (key)}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
w &&
|
||||
Plotly.newPlot(
|
||||
divEl,
|
||||
[result],
|
||||
Array.isArray(result) ? result : [result],
|
||||
{ width: w, height: h, margin: { l: 50, r: 40, b: 40, t: 40, pad: 4 } },
|
||||
{ responsive: true, displayModeBar: false }
|
||||
)
|
||||
|
||||
@@ -260,7 +260,8 @@
|
||||
on:click={() => toggleRow(row, rowIndex)}
|
||||
>
|
||||
<div class="center-center h-full w-full flex-wrap gap-1 ">
|
||||
{#each actionButtons as actionButton, actionIndex (actionIndex)}
|
||||
{#each actionButtons as actionButton, actionIndex (actionButton?.id)}
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
<div
|
||||
on:mouseover|stopPropagation={() => {
|
||||
if (actionButton.id !== $hoverStore) {
|
||||
@@ -294,12 +295,15 @@
|
||||
extraKey={'idx' + rowIndex}
|
||||
{render}
|
||||
noWFull
|
||||
{...actionButton}
|
||||
preclickAction={async () => {
|
||||
toggleRow(row, rowIndex)
|
||||
}}
|
||||
id={actionButton.id}
|
||||
customCss={actionButton.customCss}
|
||||
configuration={actionButton.configuration}
|
||||
recomputeIds={actionButton.recomputeIds}
|
||||
extraQueryParams={{ row: row.original }}
|
||||
bind:componentInput={actionButton.componentInput}
|
||||
componentInput={actionButton.componentInput}
|
||||
controls={{
|
||||
left: () => {
|
||||
if (actionIndex === 0) {
|
||||
@@ -327,12 +331,15 @@
|
||||
extraKey={'idx' + rowIndex}
|
||||
{render}
|
||||
noWFull
|
||||
{...actionButton}
|
||||
id={actionButton.id}
|
||||
customCss={actionButton.customCss}
|
||||
configuration={actionButton.configuration}
|
||||
recomputeIds={actionButton.recomputeIds}
|
||||
preclickAction={async () => {
|
||||
toggleRow(row, rowIndex)
|
||||
}}
|
||||
extraQueryParams={{ row: row.original }}
|
||||
bind:componentInput={actionButton.componentInput}
|
||||
componentInput={actionButton.componentInput}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -358,9 +365,9 @@
|
||||
<div class="flex flex-col h-full w-full overflow-auto">
|
||||
<Alert title="Parsing issues" type="error" size="xs" class="h-full w-full ">
|
||||
The result should be an array of objects. Received:
|
||||
<pre class="w-full bg-white p-2 rounded-md">
|
||||
{JSON.stringify(result, null, 4)}
|
||||
</pre>
|
||||
<pre class="w-full bg-white p-2 rounded-md whitespace-pre-wrap"
|
||||
>{JSON.stringify(result, null, 4)}</pre
|
||||
>
|
||||
</Alert>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
export let outputs: { result: Output<any>; loading: Output<boolean> }
|
||||
export let extraKey = ''
|
||||
export let doNotRecomputeOnInputChanged: boolean = false
|
||||
export let loading = false
|
||||
|
||||
const {
|
||||
worldStore,
|
||||
@@ -63,6 +64,8 @@
|
||||
let runnableInputValues: Record<string, any> = {}
|
||||
let executeTimeout: NodeJS.Timeout | undefined = undefined
|
||||
|
||||
$: outputs.loading?.set(loading)
|
||||
|
||||
function setDebouncedExecute() {
|
||||
executeTimeout && clearTimeout(executeTimeout)
|
||||
executeTimeout = setTimeout(() => {
|
||||
@@ -142,7 +145,7 @@
|
||||
|
||||
async function executeComponent(noToast = false, inlineScriptOverride?: InlineScript) {
|
||||
if (runnable?.type === 'runnableByName' && runnable.inlineScript?.language === 'frontend') {
|
||||
outputs.loading?.set(true)
|
||||
loading = true
|
||||
try {
|
||||
const r = await eval_like(
|
||||
runnable.inlineScript?.content,
|
||||
@@ -158,7 +161,7 @@
|
||||
} catch (e) {
|
||||
sendUserToast('Error running frontend script: ' + e.message, true)
|
||||
}
|
||||
outputs.loading?.set(false)
|
||||
loading = false
|
||||
return
|
||||
}
|
||||
if (noBackend) {
|
||||
@@ -171,7 +174,7 @@
|
||||
return
|
||||
}
|
||||
|
||||
outputs.loading?.set(true)
|
||||
loading = true
|
||||
|
||||
try {
|
||||
let njob = await testJobLoader?.abstractRun(() => {
|
||||
@@ -220,7 +223,8 @@
|
||||
$jobs = [{ job: njob, component: id }, ...$jobs]
|
||||
}
|
||||
} catch (e) {
|
||||
outputs.loading?.set(false)
|
||||
setResult({ error: e.body ?? e.message })
|
||||
loading = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +232,7 @@
|
||||
try {
|
||||
await executeComponent()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
setResult({ error: e.body ?? e.message })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +326,7 @@
|
||||
setResult(e.detail.result)
|
||||
}
|
||||
}
|
||||
outputs.loading?.set(false)
|
||||
loading = false
|
||||
}}
|
||||
bind:isLoading={testIsLoading}
|
||||
bind:job={testJob}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
export let id: string
|
||||
export let result: any = undefined
|
||||
export let initializing: boolean = true
|
||||
|
||||
export let loading: boolean = false
|
||||
export let extraQueryParams: Record<string, any> = {}
|
||||
export let autoRefresh: boolean = true
|
||||
export let runnableComponent: RunnableComponent | undefined = undefined
|
||||
@@ -100,6 +100,7 @@
|
||||
{:else if componentInput.type === 'runnable' && isRunnableDefined(componentInput)}
|
||||
<RunnableComponent
|
||||
{extraKey}
|
||||
bind:loading
|
||||
bind:this={runnableComponent}
|
||||
fields={componentInput.fields}
|
||||
bind:result
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
customCss={component.customCss}
|
||||
bind:initializing
|
||||
componentInput={component.componentInput}
|
||||
bind:actionButtons={component.actionButtons}
|
||||
actionButtons={component.actionButtons}
|
||||
{render}
|
||||
/>
|
||||
{:else if component.type === 'aggridcomponent'}
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { History } from '$lib/history'
|
||||
|
||||
import type { Writable } from 'svelte/store'
|
||||
import type { AppComponent, components } from './editor/component/components'
|
||||
import type { StyleProperty, StylePropertyKey } from './editor/componentsPanel/quickStyleProperties'
|
||||
import type {
|
||||
AppInput,
|
||||
ConnectedAppInput,
|
||||
|
||||
Reference in New Issue
Block a user