From 1d5c194f09ffba963d52e418c5954843d84ae337 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Fri, 10 Mar 2023 15:04:34 +0100 Subject: [PATCH 1/4] feat(bash): add default argument handling for bash --- backend/Cargo.lock | 1 + .../parsers/windmill-parser-bash/Cargo.toml | 3 +- .../parsers/windmill-parser-bash/src/lib.rs | 39 +++++++++++++++---- frontend/src/lib/script_helpers.ts | 1 + 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 76fd67296b..5179ccf80a 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -4892,6 +4892,7 @@ dependencies = [ "lazy_static", "phf", "regex", + "serde_json", "unicode-general-category", "windmill-common", "windmill-parser", diff --git a/backend/parsers/windmill-parser-bash/Cargo.toml b/backend/parsers/windmill-parser-bash/Cargo.toml index 0ae341ef8b..22579e82c3 100644 --- a/backend/parsers/windmill-parser-bash/Cargo.toml +++ b/backend/parsers/windmill-parser-bash/Cargo.toml @@ -16,4 +16,5 @@ unicode-general-category.workspace = true itertools.workspace = true anyhow.workspace = true regex.workspace = true -lazy_static.workspace = true \ No newline at end of file +lazy_static.workspace = true +serde_json.workspace = true \ No newline at end of file diff --git a/backend/parsers/windmill-parser-bash/src/lib.rs b/backend/parsers/windmill-parser-bash/src/lib.rs index fdd5f26fe6..a43e079cb7 100644 --- a/backend/parsers/windmill-parser-bash/src/lib.rs +++ b/backend/parsers/windmill-parser-bash/src/lib.rs @@ -1,6 +1,8 @@ #![allow(non_snake_case)] // TODO: switch to parse_* function naming +use anyhow::anyhow; use regex::Regex; +use serde_json::json; use std::collections::HashMap; use windmill_parser::{Arg, MainArgSignature, Typ}; @@ -17,19 +19,32 @@ pub fn parse_bash_sig(code: &str) -> windmill_common::error::Result anyhow::Result>> { - let mut hm = HashMap::new(); - let re = Regex::new(r#"(?m)^(\w+)="\$(\d+)"$"#).unwrap(); - for cap in re.captures_iter(code) { - hm.insert(cap[2].parse::()?, cap[1].to_string()); + let mut hm: HashMap)> = HashMap::new(); + for cap in RE.captures_iter(code) { + hm.insert( + cap.get(2) + .or(cap.get(3)) + .and_then(|x| x.as_str().parse::().ok()) + .ok_or_else(|| anyhow!("Impossible to parse arg digit"))?, + ( + cap[1].to_string(), + cap.get(4).map(|x| x.as_str().to_string()), + ), + ); } let mut args = vec![]; for i in 1..20 { if hm.contains_key(&i) { + let (name, default) = hm.get(&i).unwrap(); args.push(Arg { - name: hm[&i].clone(), + name: name.clone(), typ: Typ::Str(None), - default: None, + default: default.clone().map(|x| json!(x)), otyp: None, has_default: false, }); @@ -43,6 +58,8 @@ fn parse_file(code: &str) -> anyhow::Result>> { #[cfg(test)] mod tests { + use serde_json::json; + use super::*; #[test] @@ -50,8 +67,7 @@ mod tests { let code = r#" token="$1" image="$2" -digest="${3:-latest}" -foo="$4" +digest="${3:-latest with spaces}" "#; //println!("{}", serde_json::to_string()?); @@ -74,6 +90,13 @@ foo="$4" typ: Typ::Str(None), default: None, has_default: false + }, + Arg { + otyp: None, + name: "digest".to_string(), + typ: Typ::Str(None), + default: Some(json!("latest with spaces")), + has_default: false } ] } diff --git a/frontend/src/lib/script_helpers.ts b/frontend/src/lib/script_helpers.ts index c254c43615..b017334d3d 100644 --- a/frontend/src/lib/script_helpers.ts +++ b/frontend/src/lib/script_helpers.ts @@ -114,6 +114,7 @@ export async function main( export const BASH_INIT_CODE = `# arguments of the form X="$I" are parsed as parameters X of type string msg="$1" +dflt="\${2:-default value}" # the last line of the stdout is the return value echo "Hello $msg" From bc440f8d4154ce464c0e027d93b7a0a3b76d782e Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Fri, 10 Mar 2023 18:41:27 +0100 Subject: [PATCH 2/4] feat(frontend-apps): add variable picker for static string input on apps --- backend/windmill-api/src/apps.rs | 20 +++++++ .../src/lib/components/ResourcePicker.svelte | 1 + .../apps/components/buttons/AppButton.svelte | 4 +- .../apps/components/buttons/AppForm.svelte | 4 +- .../components/buttons/AppFormButton.svelte | 4 +- .../components/display/AppBarChart.svelte | 4 +- .../display/AppDisplayComponent.svelte | 4 +- .../apps/components/display/AppHtml.svelte | 4 +- .../apps/components/display/AppIcon.svelte | 4 +- .../apps/components/display/AppImage.svelte | 4 +- .../apps/components/display/AppMap.svelte | 4 +- .../apps/components/display/AppPdf.svelte | 4 +- .../components/display/AppPieChart.svelte | 4 +- .../components/display/AppScatterChart.svelte | 4 +- .../apps/components/display/AppText.svelte | 4 +- .../components/display/AppTimeseries.svelte | 4 +- .../display/table/AppAggridTable.svelte | 4 +- .../components/display/table/AppTable.svelte | 4 +- .../apps/components/helpers/InputValue.svelte | 4 +- .../helpers/NonRunnableComponent.svelte | 4 +- .../components/helpers/RefreshButton.svelte | 4 +- .../components/helpers/ResizeWrapper.svelte | 4 +- .../helpers/RunnableComponent.svelte | 4 +- .../components/helpers/RunnableWrapper.svelte | 4 +- .../apps/components/inputs/AppCheckbox.svelte | 4 +- .../components/inputs/AppDateInput.svelte | 4 +- .../components/inputs/AppFileInput.svelte | 4 +- .../components/inputs/AppMultiSelect.svelte | 4 +- .../components/inputs/AppNumberInput.svelte | 4 +- .../components/inputs/AppRangeInput.svelte | 4 +- .../apps/components/inputs/AppSelect.svelte | 4 +- .../components/inputs/AppSliderInputs.svelte | 4 +- .../components/inputs/AppTextInput.svelte | 4 +- .../inputs/currency/AppCurrencyInput.svelte | 4 +- .../components/layout/AppContainer.svelte | 4 +- .../apps/components/layout/AppDivider.svelte | 4 +- .../apps/components/layout/AppDrawer.svelte | 4 +- .../components/layout/AppSplitpanes.svelte | 7 ++- .../apps/components/layout/AppTabs.svelte | 8 ++- .../components/apps/editor/AppEditor.svelte | 59 +++++++++++++++++-- .../apps/editor/AppEditorHeader.svelte | 11 ++-- .../components/apps/editor/AppInputs.svelte | 4 +- .../components/apps/editor/AppPreview.svelte | 8 +-- .../apps/editor/ComponentHeader.svelte | 4 +- .../components/apps/editor/GridEditor.svelte | 7 ++- .../components/apps/editor/GridPanel.svelte | 4 +- .../apps/editor/RecomputeAllComponents.svelte | 30 +++++----- .../apps/editor/SettingsPanel.svelte | 4 +- .../apps/editor/SubGridEditor.svelte | 16 ++--- .../apps/editor/component/Component.svelte | 4 +- .../component/ComponentNavigation.svelte | 8 ++- .../apps/editor/component/default-codes.ts | 12 ++-- .../componentsPanel/ComponentList.svelte | 7 ++- .../editor/componentsPanel/CssSettings.svelte | 4 +- .../contextPanel/ComponentOutputViewer.svelte | 4 +- .../editor/contextPanel/ContextPanel.svelte | 4 +- .../EmptyInlineScript.svelte | 4 +- .../InlineScriptEditor.svelte | 4 +- .../InlineScriptsPanel.svelte | 4 +- .../InlineScriptsPanelList.svelte | 4 +- .../ComponentInputTypeEditor.svelte | 4 +- .../settingsPanel/ComponentPanel.svelte | 9 +-- .../apps/editor/settingsPanel/GridPane.svelte | 4 +- .../apps/editor/settingsPanel/GridTab.svelte | 4 +- .../settingsPanel/InputsSpecEditor.svelte | 1 + .../settingsPanel/InputsSpecsEditor.svelte | 4 +- .../settingsPanel/MoveToOtherGrid.svelte | 5 +- .../editor/settingsPanel/Recompute.svelte | 4 +- .../settingsPanel/SelectedRunnable.svelte | 4 +- .../editor/settingsPanel/TableActions.svelte | 4 +- .../inputEditor/ConnectedInputEditor.svelte | 4 +- .../inputEditor/EvalInputEditor.svelte | 4 +- .../inputEditor/StaticInputEditor.svelte | 36 ++++++++--- .../mainInput/RunnableSelector.svelte | 4 +- frontend/src/lib/components/apps/types.ts | 7 ++- 75 files changed, 291 insertions(+), 189 deletions(-) diff --git a/backend/windmill-api/src/apps.rs b/backend/windmill-api/src/apps.rs index afe569cba6..9c4cb54f9e 100644 --- a/backend/windmill-api/src/apps.rs +++ b/backend/windmill-api/src/apps.rs @@ -733,6 +733,9 @@ fn build_args( path: String, args: &Map, ) -> Result> { + // disallow var and res access in args coming from the user for security reasons + args.into_iter() + .try_for_each(|x| disallow_var_res_access(x.1))?; let static_args = policy .triggerables .get(&path) @@ -753,3 +756,20 @@ fn build_args( } Ok(args) } + +fn disallow_var_res_access(args: &serde_json::Value) -> Result<()> { + match args { + Value::Object(v) => v.into_iter().try_for_each(|x| disallow_var_res_access(x.1)), + Value::Array(arr) => arr.into_iter().try_for_each(|v| disallow_var_res_access(v)), + Value::String(s) => { + if s.starts_with("$var:") || s.starts_with("$res:") { + Err(Error::BadRequest(format!( + "For security reasons, variable or resource access is not allowed as dynamic argument" + ))) + } else { + Ok(()) + } + } + _ => Ok(()), + } +} diff --git a/frontend/src/lib/components/ResourcePicker.svelte b/frontend/src/lib/components/ResourcePicker.svelte index 2e12def37b..67ec0185e3 100644 --- a/frontend/src/lib/components/ResourcePicker.svelte +++ b/frontend/src/lib/components/ResourcePicker.svelte @@ -58,6 +58,7 @@ on:refresh={async (e) => { await loadResources(resourceType) value = e.detail + valueSelect = { value: e.detail, label: e.detail } }} newPageOAuth bind:this={appConnect} diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index da67a9a738..4256e86729 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -3,7 +3,7 @@ import { getContext } from 'svelte' import type { AppInput } from '../../inputType' import type { Output } from '../../rx' - import type { AppEditorContext, ComponentCustomCSS } from '../../types' + import type { AppViewerContext, ComponentCustomCSS } from '../../types' import AlignWrapper from '../helpers/AlignWrapper.svelte' import InputValue from '../helpers/InputValue.svelte' import type RunnableComponent from '../helpers/RunnableComponent.svelte' @@ -26,7 +26,7 @@ export const staticOutputs: string[] = ['loading', 'result'] - const { runnableComponents, worldStore, app } = getContext('AppEditorContext') + const { runnableComponents, worldStore, app } = getContext('AppViewerContext') let labelValue: string let color: ButtonType.Color diff --git a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte index 78944e7790..7cf3ca59a4 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte @@ -5,7 +5,7 @@ import { Icon } from 'svelte-awesome' import type { AppInput } from '../../inputType' import type { Output } from '../../rx' - import type { AppEditorContext, ComponentCustomCSS } from '../../types' + import type { AppViewerContext, ComponentCustomCSS } from '../../types' import { concatCustomCss } from '../../utils' import AlignWrapper from '../helpers/AlignWrapper.svelte' import InputValue from '../helpers/InputValue.svelte' @@ -24,7 +24,7 @@ export const staticOutputs: string[] = ['loading', 'result'] const { app, runnableComponents, worldStore, stateId } = - getContext('AppEditorContext') + getContext('AppViewerContext') let labelValue: string = 'Default label' let color: ButtonType.Color diff --git a/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte index 8b54393951..3e03bbe555 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte @@ -5,7 +5,7 @@ import { Icon } from 'svelte-awesome' import type { AppInput } from '../../inputType' import type { Output } from '../../rx' - import type { AppEditorContext, ComponentCustomCSS } from '../../types' + import type { AppViewerContext, ComponentCustomCSS } from '../../types' import AlignWrapper from '../helpers/AlignWrapper.svelte' import InputValue from '../helpers/InputValue.svelte' import type RunnableComponent from '../helpers/RunnableComponent.svelte' @@ -26,7 +26,7 @@ export const staticOutputs: string[] = ['loading', 'result'] - const { app, runnableComponents, worldStore } = getContext('AppEditorContext') + const { app, runnableComponents, worldStore } = getContext('AppViewerContext') let labelValue: string = 'Default label' let color: ButtonType.Color diff --git a/frontend/src/lib/components/apps/components/display/AppBarChart.svelte b/frontend/src/lib/components/apps/components/display/AppBarChart.svelte index 3dc5aa6140..7cccf90641 100644 --- a/frontend/src/lib/components/apps/components/display/AppBarChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppBarChart.svelte @@ -17,7 +17,7 @@ import InputValue from '../helpers/InputValue.svelte' import { concatCustomCss } from '../../utils' import { getContext } from 'svelte' - import type { AppEditorContext, ComponentCustomCSS } from '../../types' + import type { AppViewerContext, ComponentCustomCSS } from '../../types' export let id: string export let componentInput: AppInput | undefined @@ -27,7 +27,7 @@ export let render: boolean export const staticOutputs: string[] = ['loading', 'result'] - const { app } = getContext('AppEditorContext') + const { app } = getContext('AppViewerContext') ChartJS.register( Title, diff --git a/frontend/src/lib/components/apps/components/display/AppDisplayComponent.svelte b/frontend/src/lib/components/apps/components/display/AppDisplayComponent.svelte index 99c2a0f832..eb970d233c 100644 --- a/frontend/src/lib/components/apps/components/display/AppDisplayComponent.svelte +++ b/frontend/src/lib/components/apps/components/display/AppDisplayComponent.svelte @@ -5,7 +5,7 @@ import type { AppInput } from '../../inputType' import { IS_APP_PUBLIC_CONTEXT_KEY, - type AppEditorContext, + type AppViewerContext, type ComponentCustomCSS } from '../../types' import RunnableWrapper from '../helpers/RunnableWrapper.svelte' @@ -17,7 +17,7 @@ export let render: boolean const requireHtmlApproval = getContext(IS_APP_PUBLIC_CONTEXT_KEY) - const { app } = getContext('AppEditorContext') + const { app } = getContext('AppViewerContext') let result: any = undefined export const staticOutputs: string[] = ['result', 'loading'] diff --git a/frontend/src/lib/components/apps/components/display/AppHtml.svelte b/frontend/src/lib/components/apps/components/display/AppHtml.svelte index 8ce2ef735c..a8e5c45eb0 100644 --- a/frontend/src/lib/components/apps/components/display/AppHtml.svelte +++ b/frontend/src/lib/components/apps/components/display/AppHtml.svelte @@ -1,7 +1,7 @@ @@ -284,3 +300,36 @@ {:else} App editor not available to operators {/if} + + { + $pickVariableCallback?.(path) + }} + itemName="Variable" + extraField="path" + loadItems={async () => + (await VariableService.listVariable({ workspace: $workspaceStore ?? '' })).map((x) => ({ + name: x.path, + ...x + }))} +> +
+ +
+
+ + diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte index 04500d811e..754b2ad88d 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte @@ -27,7 +27,7 @@ import Tooltip from '$lib/components/Tooltip.svelte' import { AppService, Job, Policy } from '$lib/gen' import { redo, undo } from '$lib/history' - import { userStore, workspaceStore } from '$lib/stores' + import { workspaceStore } from '$lib/stores' import { faBug, faClipboard, @@ -61,7 +61,7 @@ StaticAppInput, UserAppInput } from '../inputType' - import type { AppEditorContext } from '../types' + import type { AppEditorContext, AppViewerContext } from '../types' import { allItems, toStatic } from '../utils' import AppExportButton from './AppExportButton.svelte' import AppInputs from './AppInputs.svelte' @@ -90,9 +90,10 @@ errorByComponent, openDebugRun, focusedGrid, - selectedComponent, - history - } = getContext('AppEditorContext') + selectedComponent + } = getContext('AppViewerContext') + + const { history } = getContext('AppEditorContext') const loading = { publish: false, diff --git a/frontend/src/lib/components/apps/editor/AppInputs.svelte b/frontend/src/lib/components/apps/editor/AppInputs.svelte index 6fed2e3b78..15c5afeef8 100644 --- a/frontend/src/lib/components/apps/editor/AppInputs.svelte +++ b/frontend/src/lib/components/apps/editor/AppInputs.svelte @@ -2,11 +2,11 @@ import { Alert } from '$lib/components/common' import Toggle from '$lib/components/Toggle.svelte' import { getContext } from 'svelte' - import type { AppEditorContext } from '../types' + import type { AppViewerContext } from '../types' import AppComponentInput from './AppComponentInput.svelte' import InputsSpecsEditor from './settingsPanel/InputsSpecsEditor.svelte' - const { app } = getContext('AppEditorContext') + const { app } = getContext('AppViewerContext') let resourceOnly: boolean = true diff --git a/frontend/src/lib/components/apps/editor/AppPreview.svelte b/frontend/src/lib/components/apps/editor/AppPreview.svelte index dbd360beee..8d926d51be 100644 --- a/frontend/src/lib/components/apps/editor/AppPreview.svelte +++ b/frontend/src/lib/components/apps/editor/AppPreview.svelte @@ -4,7 +4,7 @@ import { buildWorld, type World } from '../rx' import type { App, - AppEditorContext, + AppViewerContext, ConnectingInput, EditorBreakpoint, EditorMode @@ -40,7 +40,7 @@ const runnableComponents = writable Promise>>({}) - setContext('AppEditorContext', { + setContext('AppViewerContext', { worldStore, staticOutputs, app: appStore, @@ -61,9 +61,7 @@ openDebugRun: writable(undefined), focusedGrid: writable(undefined), stateId: writable(0), - parentWidth: writable(0), - history: writable(undefined), - componentControl: writable({}) + parentWidth: writable(0) }) let mounted = false diff --git a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte index 509610ab0f..4a13c27ed8 100644 --- a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte +++ b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte @@ -1,6 +1,6 @@ diff --git a/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte b/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte index 8483406854..b87c49e738 100644 --- a/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte +++ b/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte @@ -3,9 +3,9 @@ import { ChevronDown, RefreshCw } from 'lucide-svelte' import { getContext, onMount } from 'svelte' import Button from '../../common/button/Button.svelte' - import type { AppEditorContext } from '../types' + import type { AppViewerContext } from '../types' - const { runnableComponents } = getContext('AppEditorContext') + const { runnableComponents } = getContext('AppViewerContext') let loading: boolean = false let timeout: NodeJS.Timer | undefined = undefined let interval: number | undefined = undefined @@ -14,14 +14,14 @@ $: componentNumber = Object.keys($runnableComponents).length function onClick(stopAfterClear = true) { - if(timeout) { + if (timeout) { clearInterval(timeout) timeout = undefined shouldRefresh = false - if(stopAfterClear) return; + if (stopAfterClear) return } refresh() - if(interval) { + if (interval) { shouldRefresh = true timeout = setInterval(refresh, interval) } @@ -44,12 +44,12 @@ } function visChange() { - if(document.visibilityState === 'hidden') { - if(timeout) { + if (document.visibilityState === 'hidden') { + if (timeout) { clearInterval(timeout) timeout = undefined } - } else if(shouldRefresh) { + } else if (shouldRefresh) { timeout = setInterval(refresh, interval) } } @@ -58,7 +58,7 @@ document.addEventListener('visibilitychange', visChange) return () => { document.removeEventListener('visibilitychange', visChange) - if(timeout) clearInterval(timeout) + if (timeout) clearInterval(timeout) } }) @@ -66,17 +66,19 @@
({ displayName: `Every ${i * 5} seconds`, action: () => setInter(i * 5000) - })), + })) ]} > {interval ? `${interval / 1000}s` : 'once'} diff --git a/frontend/src/lib/components/apps/editor/SettingsPanel.svelte b/frontend/src/lib/components/apps/editor/SettingsPanel.svelte index 6c17ef905c..0222cb9735 100644 --- a/frontend/src/lib/components/apps/editor/SettingsPanel.svelte +++ b/frontend/src/lib/components/apps/editor/SettingsPanel.svelte @@ -1,11 +1,11 @@ {#if $app.grid} diff --git a/frontend/src/lib/components/apps/editor/SubGridEditor.svelte b/frontend/src/lib/components/apps/editor/SubGridEditor.svelte index c5e305683e..d4cfe0f5c2 100644 --- a/frontend/src/lib/components/apps/editor/SubGridEditor.svelte +++ b/frontend/src/lib/components/apps/editor/SubGridEditor.svelte @@ -4,7 +4,7 @@ import Grid from '@windmill-labs/svelte-grid' import { twMerge } from 'tailwind-merge' import { columnConfiguration, isFixed, toggleFixed } from '../gridUtils' - import type { AppEditorContext, GridItem } from '../types' + import type { AppEditorContext, AppViewerContext, GridItem } from '../types' import Component from './component/Component.svelte' import { expandGriditem, findGridItem } from './appUtils' import { push } from '$lib/history' @@ -22,16 +22,10 @@ const dispatch = createEventDispatcher() - const { - app, - connectingInput, - selectedComponent, - focusedGrid, - mode, - parentWidth, - breakpoint, - history - } = getContext('AppEditorContext') + const { app, connectingInput, selectedComponent, focusedGrid, mode, parentWidth, breakpoint } = + getContext('AppViewerContext') + + const { history } = getContext('AppEditorContext') $: highlight = id === $focusedGrid?.parentComponentId && shouldHighlight diff --git a/frontend/src/lib/components/apps/editor/component/Component.svelte b/frontend/src/lib/components/apps/editor/component/Component.svelte index dd6188bb75..375814ac31 100644 --- a/frontend/src/lib/components/apps/editor/component/Component.svelte +++ b/frontend/src/lib/components/apps/editor/component/Component.svelte @@ -3,7 +3,7 @@ import { fade } from 'svelte/transition' import { Loader2 } from 'lucide-svelte' import { twMerge } from 'tailwind-merge' - import type { AppEditorContext } from '../../types' + import type { AppViewerContext } from '../../types' import ComponentHeader from '../ComponentHeader.svelte' import type { AppComponent } from './components' import { @@ -49,7 +49,7 @@ export let render: boolean const { staticOutputs, mode, connectingInput, app, errorByComponent } = - getContext('AppEditorContext') + getContext('AppViewerContext') let hover = false let initializing: boolean | undefined = undefined let componentContainerHeight: number = 0 diff --git a/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte b/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte index 564b9115ba..641e2cc7d0 100644 --- a/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte +++ b/frontend/src/lib/components/apps/editor/component/ComponentNavigation.svelte @@ -1,10 +1,12 @@ {#if inputSpecs} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/MoveToOtherGrid.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/MoveToOtherGrid.svelte index 298da5962d..7aec63cfaa 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/MoveToOtherGrid.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/MoveToOtherGrid.svelte @@ -4,7 +4,7 @@ import { push } from '$lib/history' import { faCopy } from '@fortawesome/free-solid-svg-icons' import { getContext } from 'svelte' - import type { App, AppEditorContext } from '../../types' + import type { App, AppEditorContext, AppViewerContext } from '../../types' import { createNewGridItem, deleteGridItem, @@ -19,7 +19,8 @@ let selectedOption: string - const { app, history } = getContext('AppEditorContext') + const { app } = getContext('AppViewerContext') + const { history } = getContext('AppEditorContext') function listAllSubGrids(app: App) { return app.subgrids ? Object.keys(app.subgrids) : [] diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/Recompute.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/Recompute.svelte index 90f05cdbde..d474caefee 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/Recompute.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/Recompute.svelte @@ -1,13 +1,13 @@ {#if componentInput?.type === 'static'} {#if componentInput.fieldType === 'number'} - + {:else if componentInput.fieldType === 'textarea'} -