diff --git a/frontend/src/lib/components/apps/components/helpers/InputValue.svelte b/frontend/src/lib/components/apps/components/helpers/InputValue.svelte index 0578b11dc0..3dcfdc8f9d 100644 --- a/frontend/src/lib/components/apps/components/helpers/InputValue.svelte +++ b/frontend/src/lib/components/apps/components/helpers/InputValue.svelte @@ -15,6 +15,8 @@ export let error: string = '' export let extraContext: Record = {} + const { componentControl } = getContext('AppViewerContext') + const dispatch = createEventDispatcher() if (input == undefined) { @@ -81,7 +83,8 @@ computeGlobalContext($worldStore, id, extraContext), true, $state, - $mode == 'dnd' + $mode == 'dnd', + $componentControl ) error = '' return r @@ -99,7 +102,8 @@ computeGlobalContext($worldStore, id, extraContext), true, $state, - $mode == 'dnd' + $mode == 'dnd', + $componentControl ) error = '' return r diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte index 4f05d12c9d..a7c4e3e355 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte @@ -45,7 +45,8 @@ errorByComponent, mode, stateId, - state + state, + componentControl } = getContext('AppViewerContext') $: autoRefresh && handleAutorefresh() @@ -161,7 +162,8 @@ computeGlobalContext($worldStore, id, {}), false, $state, - $mode == 'dnd' + $mode == 'dnd', + $componentControl ) setResult(r) $state = $state diff --git a/frontend/src/lib/components/apps/components/helpers/eval.ts b/frontend/src/lib/components/apps/components/helpers/eval.ts index a178b8269b..aca5e464d9 100644 --- a/frontend/src/lib/components/apps/components/helpers/eval.ts +++ b/frontend/src/lib/components/apps/components/helpers/eval.ts @@ -24,7 +24,7 @@ export function computeGlobalContext( function create_context_function_template(eval_string, context, noReturn: boolean) { return ` -return async function (context, state, goto) { +return async function (context, state, goto, setTab) { "use strict"; ${ Object.keys(context).length > 0 @@ -40,7 +40,7 @@ function make_context_evaluator( eval_string, context, noReturn: boolean -): (context, state, goto) => Promise { +): (context, state, goto, setTab) => Promise { let template = create_context_function_template(eval_string, context, noReturn) let functor = Function(template) return functor() @@ -51,19 +51,27 @@ export async function eval_like( context = {}, noReturn: boolean, state: any, - editor: boolean + editor: boolean, + controlComponents: Record void }> ) { let evaluator = make_context_evaluator(text, context, noReturn) - return await evaluator(context, state, async (x, newTab) => { - if (newTab || editor) { - if (!newTab) { - sendUserToast( - 'In editor mode, `goto` opens a new tab to prevent losing your work. To test the redirection , use the preview mode.' - ) + return await evaluator( + context, + state, + async (x, newTab) => { + if (newTab || editor) { + if (!newTab) { + sendUserToast( + 'In editor mode, `goto` opens a new tab to prevent losing your work. To test the redirection , use the preview mode.' + ) + } + window.open(x, '_blank') + } else { + await newTab(x) } - window.open(x, '_blank') - } else { - await goto(x) + }, + (id, index) => { + controlComponents[id]?.setTab?.(index) } - }) + ) } diff --git a/frontend/src/lib/components/apps/components/layout/AppSplitpanes.svelte b/frontend/src/lib/components/apps/components/layout/AppSplitpanes.svelte index 284dc4ab0a..6da5430e0c 100644 --- a/frontend/src/lib/components/apps/components/layout/AppSplitpanes.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppSplitpanes.svelte @@ -16,9 +16,8 @@ export let panes: number[] export let render: boolean - const { app, focusedGrid, selectedComponent } = getContext('AppViewerContext') - - const { componentControl } = getContext('AppEditorContext') + const { app, focusedGrid, selectedComponent, componentControl } = + getContext('AppViewerContext') function onFocus() { $focusedGrid = { diff --git a/frontend/src/lib/components/apps/components/layout/AppTabs.svelte b/frontend/src/lib/components/apps/components/layout/AppTabs.svelte index 818460e789..8e76c36f34 100644 --- a/frontend/src/lib/components/apps/components/layout/AppTabs.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppTabs.svelte @@ -19,11 +19,9 @@ export let initializing: boolean | undefined = true export const staticOutputs: string[] = ['selectedTabIndex'] - const { app, worldStore, focusedGrid, selectedComponent, mode } = + const { app, worldStore, focusedGrid, selectedComponent, mode, componentControl } = getContext('AppViewerContext') - const { componentControl } = getContext('AppEditorContext') - let selected: string = tabs[0] let kind: 'tabs' | 'sidebar' | 'invisibleOnView' | undefined = undefined let tabHeight: number = 0 @@ -78,6 +76,9 @@ return true } return false + }, + setTab: (tab: number) => { + selected = tabs[tab] } } diff --git a/frontend/src/lib/components/apps/editor/AppEditor.svelte b/frontend/src/lib/components/apps/editor/AppEditor.svelte index 675684201a..bedc6f8744 100644 --- a/frontend/src/lib/components/apps/editor/AppEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditor.svelte @@ -89,12 +89,12 @@ focusedGrid, stateId: writable(0), parentWidth: writable(0), - state: writable({}) + state: writable({}), + componentControl: writable({}) }) setContext('AppEditorContext', { history, - componentControl: writable({}), pickVariableCallback }) diff --git a/frontend/src/lib/components/apps/editor/AppPreview.svelte b/frontend/src/lib/components/apps/editor/AppPreview.svelte index 5c1f4019fd..466bfea36b 100644 --- a/frontend/src/lib/components/apps/editor/AppPreview.svelte +++ b/frontend/src/lib/components/apps/editor/AppPreview.svelte @@ -63,12 +63,12 @@ focusedGrid: writable(undefined), stateId: writable(0), parentWidth: writable(0), - state: writable({}) + state: writable({}), + componentControl: writable({}) }) setContext('AppEditorContext', { history: undefined, - componentControl: writable({}), pickVariableCallback: writable(undefined) }) diff --git a/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte b/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte index 694e0c7c89..d9c463d356 100644 --- a/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte +++ b/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte @@ -12,10 +12,10 @@ import { push } from '$lib/history' import { sendUserToast } from '$lib/utils' - const { app, selectedComponent, breakpoint, focusedGrid } = + const { app, selectedComponent, breakpoint, focusedGrid, componentControl } = getContext('AppViewerContext') - const { componentControl, history } = getContext('AppEditorContext') + const { history } = getContext('AppEditorContext') let tempGridItem: GridItem | undefined = undefined let copiedGridItem: GridItem | undefined = undefined diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts index 46e899eeb2..9c5bec41ea 100644 --- a/frontend/src/lib/components/apps/types.ts +++ b/frontend/src/lib/components/apps/types.ts @@ -136,11 +136,16 @@ export type AppViewerContext = { stateId: Writable parentWidth: Writable state: Writable> + componentControl: Writable< + Record< + string, + { left?: () => boolean; right?: () => boolean; setTab?: (index: number) => void } + > + > } export type AppEditorContext = { history: History | undefined - componentControl: Writable boolean; right?: () => boolean }>> pickVariableCallback: Writable<((path: string) => void) | undefined> } diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts index e72de7e0ce..d19c8e5dfa 100644 --- a/frontend/src/lib/components/apps/utils.ts +++ b/frontend/src/lib/components/apps/utils.ts @@ -177,7 +177,13 @@ export function buildExtraLib( return `${cs} ${hasRows ? 'declare const row: Record;' : ''} -${goto ? 'declare const goto: async (path: string, newTab?: boolean) => void)' : ''} +${ + goto + ? `declare async function goto(path: string, newTab?: boolean): Promise; +declare function setTab(id: string, index: string): void; +` + : '' +} declare const state: ${JSON.stringify(state)}; ` }