diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte index f8a44f535c..f7e31a0b4f 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte @@ -7,10 +7,10 @@ import { AppService, type CompletedJob } from '$lib/gen' import { defaultIfEmptyString, emptySchema, sendUserToast } from '$lib/utils' import { getContext, onMount } from 'svelte' + import { computeFields } from '../../editor/inlineScriptsPanel/utils' import type { AppInputs, Runnable } from '../../inputType' import type { Output } from '../../rx' import type { AppEditorContext } from '../../types' - import { fieldTypeToTsType, schemaToInputsSpec } from '../../utils' import InputValue from './InputValue.svelte' import RefreshButton from './RefreshButton.svelte' @@ -113,7 +113,7 @@ if (inlineScript) { const newSchema = inlineScript.schema - const newFields = reloadInputs(newSchema) + const newFields = computeFields(newSchema, defaultUserInput, fields) if (JSON.stringify(newFields) !== JSON.stringify(fields)) { setTimeout(() => { @@ -124,39 +124,6 @@ } } - // When the schema is loaded, we need to update the inputs spec - // in order to render the inputs the component panel - function reloadInputs(schema: Schema) { - let schemaCopy: Schema = JSON.parse(JSON.stringify(schema)) - - const result = {} - const newInputs = schemaToInputsSpec(schemaCopy, defaultUserInput) - if (!fields) { - return newInputs - } - Object.keys(newInputs).forEach((key) => { - const newInput = newInputs[key] - const oldInput = fields[key] - - // If the input is not present in the old inputs, add it - if (oldInput === undefined) { - result[key] = newInput - } else { - if ( - fieldTypeToTsType(newInput.fieldType) !== fieldTypeToTsType(oldInput.fieldType) || - newInput.format !== oldInput.format || - newInput.subFieldType !== oldInput.subFieldType - ) { - result[key] = newInput - } else { - result[key] = oldInput - } - } - }) - - return result - } - $: schemaStripped = runnable && stripSchema(fields) function stripSchema(inputs: AppInputs): Schema { diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte index 3b0feb3f02..f07761116f 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte @@ -7,10 +7,12 @@ import { workspaceStore } from '$lib/stores' import { emptySchema, getScriptByPath } from '$lib/utils' import { faCodeBranch, faExternalLinkAlt, faEye, faPen } from '@fortawesome/free-solid-svg-icons' - import type { AppInput, ResultAppInput } from '../../inputType' - import { clearResultAppInput } from '../../utils' + import { onMount } from 'svelte' + import type { AppInput, RunnableByPath } from '../../inputType' + import { clearResultAppInput, schemaToInputsSpec } from '../../utils' import EmptyInlineScript from './EmptyInlineScript.svelte' import InlineScriptEditor from './InlineScriptEditor.svelte' + import { computeFields } from './utils' export let componentInput: AppInput | undefined export let id: string @@ -39,6 +41,26 @@ let drawerFlowViewer: Drawer let flowPath: string = '' + + async function refreshScript(x: RunnableByPath) { + let { schema } = await getScriptByPath(x.path) + if (JSON.stringify(x.schema) != JSON.stringify(schema)) { + x.schema = schema + if (componentInput?.type == 'runnable') { + componentInput.fields = computeFields(schema, false, componentInput.fields) + } + componentInput = componentInput + } + } + + $: if ( + componentInput && + componentInput.type == 'runnable' && + componentInput?.runnable?.type === 'runnableByPath' && + componentInput.runnable.runType == 'script' + ) { + refreshScript(componentInput.runnable) + } diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte index b9a2872d7b..fc6c969769 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte @@ -14,7 +14,7 @@ const { app, selectedComponent, lazyGrid } = getContext('AppEditorContext') let list: HTMLElement - function selectInlineScript(id: string) { + function selectScript(id: string) { selectedScriptComponentId = id if (!id.startsWith('unused-') || !id.startsWith('bg_')) { $selectedComponent = selectedScriptComponentId @@ -24,19 +24,10 @@ $: runnables = getAppScripts($lazyGrid) // When selected component changes, update selectedScriptComponentId - $: if (selectedComponent) { + $: if ($selectedComponent != selectedScriptComponentId) { selectedScriptComponentId = $selectedComponent } - // Doesn't work for some reason - // $: if (selectedScriptComponentId) { - // const selected = document.getElementById(PREFIX + selectedScriptComponentId) - // if(selected) { - // const top = selected.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop - // list.scrollTo({ top, behavior: 'smooth' }) - // } - // } - function createBackgroundScript() { let index = 0 let newScriptPath = `Background Script ${index}` @@ -58,7 +49,7 @@ fields: {} }) $app.hiddenInlineScripts = $app.hiddenInlineScripts - selectInlineScript(`bg_${$app.hiddenInlineScripts.length - 1}`) + selectScript(`bg_${$app.hiddenInlineScripts.length - 1}`) } @@ -73,7 +64,7 @@ id={PREFIX + id} class="border flex gap-1 truncate font-normal justify-between w-full items-center py-1 px-2 rounded-sm duration-200 {selectedScriptComponentId === id ? 'border-blue-500 bg-blue-100' : 'hover:bg-blue-50'}" - on:click={() => selectInlineScript(id)} + on:click={() => selectScript(id)} > {name}
@@ -92,7 +83,7 @@ id={PREFIX + id} class="border flex gap-1 truncate font-normal justify-between w-full items-center py-1 px-2 rounded-sm duration-200 {selectedScriptComponentId === id ? 'border-blue-500 bg-blue-100' : 'hover:bg-blue-50'}" - on:click={() => selectInlineScript(id)} + on:click={() => selectScript(id)} > {unusedInlineScript.name} Detached @@ -115,7 +106,7 @@ id={PREFIX + id} class="border flex gap-1 truncate font-normal justify-between w-full items-center py-1 px-2 rounded-sm duration-200 {selectedScriptComponentId === id ? 'border-blue-500 bg-blue-100' : 'hover:bg-blue-50'}" - on:click={() => selectInlineScript(id)} + on:click={() => selectScript(id)} > {name} {id} @@ -146,7 +137,7 @@ id={PREFIX + id} class="border flex gap-1 truncate font-normal justify-between w-full items-center py-1 px-2 rounded-sm duration-200 {selectedScriptComponentId === id ? 'border-blue-500 bg-blue-100' : 'hover:bg-blue-50'}" - on:click={() => selectInlineScript(id)} + on:click={() => selectScript(id)} > {name} {id} diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/utils.ts b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/utils.ts index ed92e8bed9..a877eae92d 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/utils.ts +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/utils.ts @@ -1,5 +1,7 @@ -import type { Runnable } from "../../inputType" +import type { Schema } from "$lib/common"; +import type { AppInputs, Runnable } from "../../inputType" import type { GridItem } from "../../types" +import { fieldTypeToTsType, schemaToInputsSpec } from "../../utils"; import type { AppComponent } from "../Component.svelte"; export interface AppScriptsList { @@ -7,6 +9,39 @@ export interface AppScriptsList { imported: { name: string; id: string }[] } +// When the schema is loaded, we need to update the inputs spec +// in order to render the inputs the component panel +export function computeFields(schema: Schema, defaultUserInput: boolean, fields: AppInputs) { + let schemaCopy: Schema = JSON.parse(JSON.stringify(schema)) + + const result = {} + const newInputs = schemaToInputsSpec(schemaCopy, defaultUserInput) + if (!fields) { + return newInputs + } + Object.keys(newInputs).forEach((key) => { + const newInput = newInputs[key] + const oldInput = fields[key] + + // If the input is not present in the old inputs, add it + if (oldInput === undefined) { + result[key] = newInput + } else { + if ( + fieldTypeToTsType(newInput.fieldType) !== fieldTypeToTsType(oldInput.fieldType) || + newInput.format !== oldInput.format || + newInput.subFieldType !== oldInput.subFieldType + ) { + result[key] = newInput + } else { + result[key] = oldInput + } + } + }) + + return result +} + export function getAppScripts(grid: GridItem[]) { return grid.reduce((acc, gridComponent) => { const component: AppComponent = gridComponent.data diff --git a/frontend/src/lib/components/apps/inputType.ts b/frontend/src/lib/components/apps/inputType.ts index 8aa4fcdaf1..3366d38ffb 100644 --- a/frontend/src/lib/components/apps/inputType.ts +++ b/frontend/src/lib/components/apps/inputType.ts @@ -58,7 +58,7 @@ export type TemplateInput = { type: 'template' } -type RunnableByPath = { +export type RunnableByPath = { path: string schema: any runType: 'script' | 'flow' | 'hubscript'