From fca5bb4f557e47d8b6d08d5f411eca2375c1d8b6 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Mon, 11 Aug 2025 15:29:17 +0000 Subject: [PATCH] fix: improve app decision tree behavior --- .../src/lib/components/SimpleEditor.svelte | 1 + .../inputs/AppCodeInputComponent.svelte | 27 ++++--- .../components/layout/AppDecisionTree.svelte | 49 +++++++----- .../DecisionTreeGraphEditor.svelte | 75 +++++++------------ .../settingsPanel/InputsSpecEditor.svelte | 3 + .../inputEditor/EvalV2InputEditor.svelte | 6 +- 6 files changed, 80 insertions(+), 81 deletions(-) diff --git a/frontend/src/lib/components/SimpleEditor.svelte b/frontend/src/lib/components/SimpleEditor.svelte index e2d06f3510..e15bff18f2 100644 --- a/frontend/src/lib/components/SimpleEditor.svelte +++ b/frontend/src/lib/components/SimpleEditor.svelte @@ -370,6 +370,7 @@ return } try { + console.log('fixedOverflowWidgets', fixedOverflowWidgets) editor = meditor.create(divEl as HTMLDivElement, { ...editorConfig(code ?? '', lang, automaticLayout, fixedOverflowWidgets), model, diff --git a/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte b/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte index 25422f97a8..9566f39866 100644 --- a/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte +++ b/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte @@ -7,7 +7,11 @@ import InputValue from '../helpers/InputValue.svelte' import InitializeComponent from '../helpers/InitializeComponent.svelte' - let { id, configuration, render }: { + let { + id, + configuration, + render + }: { id: string configuration: RichConfigurations render: boolean @@ -16,10 +20,9 @@ const { componentControl, worldStore, selectedComponent, connectingInput, mode } = getContext('AppViewerContext') - let resolvedConfig = $state(initConfig( - components['codeinputcomponent'].initialData.configuration, - configuration - )) + let resolvedConfig = $state( + initConfig(components['codeinputcomponent'].initialData.configuration, configuration) + ) let code = $state(undefined) let placeholder = $state(undefined) @@ -28,9 +31,11 @@ let lastDefaultValue = $state(undefined) let lang = $derived(resolvedConfig?.lang ?? 'javascript') - let outputs = $state(initOutput($worldStore, id, { - result: '' - })) + let outputs = $state( + initOutput($worldStore, id, { + result: '' + }) + ) $effect(() => { if (defaultValue !== lastDefaultValue) { @@ -96,9 +101,3 @@ {/await} {/if} - - diff --git a/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte b/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte index dd6d6cf35a..4b21abe380 100644 --- a/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte @@ -13,6 +13,7 @@ import Badge from '$lib/components/common/badge/Badge.svelte' import { getFirstNode, isDebugging } from '../../editor/settingsPanel/decisionTree/utils' import InputValue from '../helpers/InputValue.svelte' + import { sendUserToast } from '$lib/toast' interface Props { id: string @@ -42,10 +43,12 @@ }, {}) } + let counter = $state(0) $effect(() => { nodes resolvedConditions = untrack(() => createResolvedConditions()) resolvedNext = untrack(() => createResolvedNext()) + untrack(() => (counter += 1)) }) let everRender = $state(render) @@ -112,6 +115,7 @@ return } } + sendUserToast('No next node was an available option', true) } function updateFocusedGrid(nodeId) { currentNodeId = nodeId @@ -177,30 +181,37 @@ -{#if Object.keys(resolvedConditions).length === nodes.length} - {#each nodes ?? [] as node (node.id)} - {#each node.next ?? [] as next, conditionIndex} - {#if next.condition} + +{#key counter} + {#if Object.keys(resolvedConditions).length === nodes.length} + {#each nodes ?? [] as node (node.id)} + {#each node.next ?? [] as next, conditionIndex} + {#if next.condition} + + {/if} + {/each} + {/each} + {/if} + + {#if Object.keys(resolvedConditions).length === nodes.length} + {#each nodes ?? [] as node (node.id)} + {#if node.allowed} {/if} {/each} - {/each} -{/if} - -{#if Object.keys(resolvedConditions).length === nodes.length} - {#each nodes ?? [] as node (node.id)} - {#if node.allowed} - - {/if} - {/each} -{/if} - + {/if} +{/key} {#each Object.keys(css ?? {}) as key (key)} import { Alert, Button, Drawer, DrawerContent } from '$lib/components/common' - import { Network, Plus, Trash } from 'lucide-svelte' + import { Network, Trash } from 'lucide-svelte' import type { AppComponent, DecisionTreeNode } from '../component' import { Pane, Splitpanes } from 'svelte-splitpanes' import { getContext, setContext } from 'svelte' @@ -8,7 +8,7 @@ import Section from '$lib/components/Section.svelte' import { writable } from 'svelte/store' import DecisionTreePreview from './decisionTree/DecisionTreePreview.svelte' - import { addNewBranch, removeNode } from './decisionTree/utils' + import { removeNode } from './decisionTree/utils' import Label from '$lib/components/Label.svelte' import { debounce } from '$lib/utils' import type { AppViewerContext } from '../../types' @@ -38,17 +38,14 @@ let selectedNode = $derived(nodes?.find((node) => node.id == $selectedNodeId)) setContext('DecisionTreeEditor', { selectedNodeId }) - - let sortedSelectedNextNodes = $derived( - [...(selectedNode?.next ?? [])].sort((n1, n2) => n1.id.localeCompare(n2.id)) - ) - {}} on:open={() => {}} size="1200px"> + {}} on:open={() => {}}> @@ -114,8 +111,8 @@ /> - {#if selectedNode.next.length > 1 && sortedSelectedNextNodes} - {#each sortedSelectedNextNodes as subNode, index (subNode.id)} + {#if selectedNode.next.length > 1} + {#each selectedNode.next ?? [] as subNode, index (subNode.id)} {#if subNode.condition}
@@ -129,16 +126,22 @@ userInputEnabled={false} shouldCapitalize={true} resourceOnly={false} - fieldType={subNode.condition?.['fieldType']} - subFieldType={subNode.condition?.['subFieldType']} - format={subNode.condition?.['format']} - selectOptions={subNode.condition?.['selectOptions']} - tooltip={subNode.condition?.['tooltip']} - fileUpload={subNode.condition?.['fileUpload']} - placeholder={subNode.condition?.['placeholder']} + fieldType={'boolean'} + subFieldType={undefined} + format={undefined} + selectOptions={undefined} + tooltip={undefined} + fileUpload={undefined} + placeholder={undefined} displayType={false} fixedOverflowWidgets={false} /> + {#if index == selectedNode.next.length - 1} +
+ If no branch evaluates to true, clicking next will show an error toast. +
+ {/if} +
{`Next node id: ${subNode.id}`} @@ -151,7 +154,6 @@
{/if} {/each} - The conditions above are evaluated in order. The first condition that is met will be the branch that is taken. @@ -160,44 +162,25 @@ {#key selectedNode.id} {#if selectedNode.allowed} {/if} {/key} - - {#if selectedNode?.next.length > 0} -
- -
- {/if} {/if}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte index e87761c27f..8259a71e05 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecEditor.svelte @@ -56,6 +56,7 @@ documentationLink?: string | undefined markdownTooltip?: string | undefined securedContext?: boolean + disabled?: boolean } let { @@ -76,6 +77,7 @@ customTitle = undefined, displayType = false, allowTypeChange = true, + disabled = false, shouldFormatExpression = false, fixedOverflowWidgets = true, loading = false, @@ -274,6 +276,7 @@ {recomputeOnInputChanged} {showOnDemandOnlyToggle} {securedContext} + {disabled} /> {:else if componentInput?.type === 'upload'} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/EvalV2InputEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/EvalV2InputEditor.svelte index e8185281d4..82517a3b19 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/EvalV2InputEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/EvalV2InputEditor.svelte @@ -22,6 +22,7 @@ recomputeOnInputChanged?: boolean showOnDemandOnlyToggle?: boolean securedContext?: boolean + disabled?: boolean } let { @@ -32,7 +33,8 @@ acceptSelf = false, recomputeOnInputChanged = true, showOnDemandOnlyToggle = false, - securedContext = false + securedContext = false, + disabled = false }: Props = $props() const { @@ -68,7 +70,6 @@ } function inferDepsFromCode(code: string) { - console.log('inferDepsFromCode', id) if (componentInput) { inferDeps(code, $worldStore.outputsById, componentInput, app) } @@ -137,6 +138,7 @@ shouldBindKey={false} {extraLib} autoHeight + {disabled} {fixedOverflowWidgets} on:focus={() => { focus = true