whitelabel default timeout + test-job callbacks (#9469)

Add a configurable `defaultTimeout` to the script/flow editor whitelabel
customUi (replaces the hardcoded 300s default) and an `onTestJob` callback
on ScriptBuilder/FlowBuilder that fires with the preview job id when a test
run starts.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-06-08 14:43:07 +00:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 64b089cd23
commit 82cb7bf375
9 changed files with 36 additions and 10 deletions
@@ -133,7 +133,8 @@
onSaveDraftError,
onSaveDraftOnlyAtNewPath,
onHistoryRestore,
onNavigate
onNavigate,
onTestJob
}: FlowBuilderProps = $props()
let initialPathStore = writable(initialPath)
@@ -1267,11 +1268,14 @@
bind:localModuleStates
bind:this={flowPreviewButtons}
{loading}
onRunPreview={() => {
onRunPreview={(jobId) => {
stepsInputArgs.resetManuallyEditedArgs()
modulesTestStates.hideJobsInGraph()
localModuleStates = {}
showJobStatus = true
if (jobId) {
onTestJob?.({ jobId })
}
}}
/>
{/snippet}
@@ -59,7 +59,7 @@
scrollTop?: number
localModuleStates?: Record<string, GraphModuleState>
localDurationStatuses?: Record<string, DurationStatus>
onRunPreview?: () => void
onRunPreview?: (jobId?: string) => void
render?: boolean
onJobDone?: () => void
upToId?: string | undefined
@@ -200,7 +200,7 @@
savedArgs = $state.snapshot(previewArgs.val)
inputSelected = undefined
}
onRunPreview?.()
onRunPreview?.(newJobId)
} catch (e) {
sendUserToast('Could not run preview', true, undefined, e.toString())
isRunning = false
@@ -134,6 +134,7 @@
onSaveDraftError,
onSaveDraft,
onNavigate,
onTestJob,
disableAi,
initialTestPanelCollapsed = false,
initialPathChosen = false
@@ -1565,7 +1566,7 @@
if (script.timeout && script.timeout != undefined) {
script.timeout = undefined
} else {
script.timeout = 300
script.timeout = customUi?.defaultTimeout ?? 300
}
}}
options={{
@@ -2084,6 +2085,7 @@
{disableAi}
bind:selectedTab={selectedInputTab}
{customUi}
{onTestJob}
collabMode
edit={initialPath != ''}
on:format={() => {
@@ -160,6 +160,9 @@
modules?: { [key: string]: ScriptModule } | null
editorBarRight?: import('svelte').Snippet
enablePreprocessorSnippet?: boolean
// Fired whenever a test run is started from this editor, with the
// preview job id. Used by whitelabel embedders to track test jobs.
onTestJob?: (e: { jobId: string }) => void
// When true the right-hand test/run pane mounts collapsed. The user
// can still expand it via `toggleTestPanel`. Defaults to false so the
// regular /scripts/edit route keeps its current open-by-default UX;
@@ -199,6 +202,7 @@
modules = $bindable(undefined),
editorBarRight,
enablePreprocessorSnippet = false,
onTestJob,
initialTestPanelCollapsed = false
}: Props = $props()
@@ -729,6 +733,9 @@
undefined,
activeModuleTab !== null ? undefined : modules
)
if (job) {
onTestJob?.({ jobId: job })
}
logPanel?.setFocusToLogs()
return job
}
@@ -1357,9 +1364,7 @@
// width (Svelte wires a ResizeObserver for bind:clientWidth).
let splitContainerWidth = $state(0)
const TEST_PANE_MIN_PX = 400
const testPaneMinPercent = $derived(
paneMinPercent(splitContainerWidth, TEST_PANE_MIN_PX)
)
const testPaneMinPercent = $derived(paneMinPercent(splitContainerWidth, TEST_PANE_MIN_PX))
// Raw user-controlled test size (what the splitter wrote, or what the
// toggle set). The size we actually pass to <Pane> is clamped to the
+6
View File
@@ -44,6 +44,9 @@ export type FlowBuilderWhitelabelCustomUi = {
aiSandbox?: boolean
suggestIntegration?: boolean
suggestScript?: boolean
// Default timeout (in seconds) prefilled when enabling a custom step timeout.
// Defaults to 300 (5 minutes) when unset.
defaultTimeout?: number
}
export type DisplayResultUi = {
@@ -130,4 +133,7 @@ export type ScriptBuilderWhitelabelCustomUi = {
editorBar?: EditorBarUi
previewPanel?: PreviewPanelUi
tagSelectPlaceholder?: string
// Default timeout (in seconds) prefilled when enabling a custom script timeout.
// Defaults to 300 (5 minutes) when unset.
defaultTimeout?: number
}
@@ -51,4 +51,7 @@ export type FlowBuilderProps = {
onDetails?: ({ path }: { path: string }) => void
onHistoryRestore?: () => void
onNavigate?: (item: WorkspaceItem) => void
// Fired whenever a test run is started from the flow editor, with the
// preview job id. Used by whitelabel embedders to track test jobs.
onTestJob?: (e: { jobId: string }) => void
}
@@ -13,6 +13,7 @@
import PropPickerWrapper from '$lib/components/flows/propPicker/PropPickerWrapper.svelte'
import type { FlowEditorContext } from '../types'
import { getStepPropPicker } from '../previousResults'
import type { FlowBuilderWhitelabelCustomUi } from '$lib/components/custom_ui'
interface Props {
flowModule: FlowModule
@@ -24,6 +25,8 @@
const { flowStore, flowStateStore, previewArgs } =
getContext<FlowEditorContext>('FlowEditorContext')
const customUi = getContext<FlowBuilderWhitelabelCustomUi | undefined>('customUi')
let schema = $state(emptySchema())
schema.properties['timeout'] = {
type: 'number'
@@ -69,7 +72,7 @@
} else {
flowModule.timeout = {
type: 'static',
value: 300
value: customUi?.defaultTimeout ?? 300
}
}
}}
@@ -14,7 +14,7 @@
interface Props {
loading?: boolean
onRunPreview?: () => void
onRunPreview?: (jobId?: string) => void
onJobDone?: () => void
localModuleStates?: Record<string, GraphModuleState>
suspendStatus: StateStore<Record<string, { job: Job; nb: number }>>
@@ -48,6 +48,9 @@ export interface ScriptBuilderProps {
onSeeDetails?: (e: { path: string }) => void
onSaveDraftError?: (e: { path: string; error: any }) => void
onNavigate?: (item: WorkspaceItem) => void
// Fired whenever a test run is started from the script editor, with the
// preview job id. Used by whitelabel embedders to track test jobs.
onTestJob?: (e: { jobId: string }) => void
// Forwarded to the underlying ScriptEditor. When true, the right-hand
// test/run pane opens collapsed. Used by the session preview.
initialTestPanelCollapsed?: boolean