diff --git a/frontend/BUGS.txt b/frontend/BUGS.txt new file mode 100644 index 0000000000..aae0762777 --- /dev/null +++ b/frontend/BUGS.txt @@ -0,0 +1,39 @@ +# Svelte 5 Migration - Bug Report +# Testing started: 2026-03-02 + +## Warnings (not blocking but worth fixing) + +1. [WARNING] binding_property_non_reactive in Grid.svelte:372:5 + - `bind:this={moveResizes[item.id]}` is binding to a non-reactive property + - File: src/lib/components/apps/svelte-grid/Grid.svelte + - Appears multiple times in App editor + - Status: NOT FIXED (non-blocking warning) + +2. [WARNING] legacy_recursive_reactive_block in RecomputeAllComponents.svelte + - Migrated `$:` reactive block that both accesses and updates the same reactive value + - File: src/lib/components/apps/editor/RecomputeAllComponents.svelte + - May cause recursive updates when converted to $effect + - Status: NOT FIXED (non-blocking warning) + +3. [WARNING] ownership_invalid_mutation in SchemaForm.svelte:70:16 + - Mutating unbound props (`schema`) is strongly discouraged + - Parent: src/lib/components/ApiConnectForm.svelte should use `bind:schema={...}` + - Appears when opening PostgreSQL resource creation form + - Status: NOT FIXED (non-blocking warning) + +4. [WARNING] ownership_invalid_binding in InputTransformSchemaForm.svelte + - Passes `schema` to InputTransformForm.svelte with `bind:`, but parent Pane.svelte didn't declare `schema` as binding + - Appears in flow editor when adding a TypeScript step + - Status: NOT FIXED (non-blocking warning) + +## Bugs + +1. [BUG] state_descriptors_fixed in Chart.svelte (Queue metrics drawer) + - Error: "Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`." + - Triggered by: Clicking "Queue metrics" on /workers page + - File: src/lib/components/chartjs-wrappers/Chart.svelte + - Root cause: Chart.js's `listenArrayEvents` calls Object.defineProperty on data arrays that are Svelte 5 $state proxies, which reject non-standard property descriptors + - Fix: Use $state.snapshot() to pass plain copies of data and options to Chart.js + - Status: FIXED + + diff --git a/frontend/src/lib/components/AppConnectDrawer.svelte b/frontend/src/lib/components/AppConnectDrawer.svelte index d8ad4cd389..8156b2c1f4 100644 --- a/frontend/src/lib/components/AppConnectDrawer.svelte +++ b/frontend/src/lib/components/AppConnectDrawer.svelte @@ -1,4 +1,6 @@ @@ -47,7 +54,7 @@ @@ -68,7 +75,7 @@ {})}>Back {/if} {#if isGoogleSignin} - + workspace)) { + $workspaceStore = untrack(() => workspace) } onMount(async () => { diff --git a/frontend/src/lib/components/AppWrapper.svelte b/frontend/src/lib/components/AppWrapper.svelte index 37e5bdfc2e..9c6cd9756d 100644 --- a/frontend/src/lib/components/AppWrapper.svelte +++ b/frontend/src/lib/components/AppWrapper.svelte @@ -1,10 +1,11 @@ diff --git a/frontend/src/lib/components/AutheliaSetting.svelte b/frontend/src/lib/components/AutheliaSetting.svelte index bd32b632a9..a3aa2e3458 100644 --- a/frontend/src/lib/components/AutheliaSetting.svelte +++ b/frontend/src/lib/components/AutheliaSetting.svelte @@ -1,16 +1,20 @@ - + + import { run } from 'svelte/legacy'; + import IconedResourceType from './IconedResourceType.svelte' import Toggle from './Toggle.svelte' import SettingCard from './instanceSettings/SettingCard.svelte' - export let value: any + interface Props { + value: any; + } + + let { value = $bindable() }: Props = $props(); - $: enabled = value != undefined - // Initialize org from existing auth_url - $: org = value?.connect_config?.auth_url?.replace('/application/o/authorize/', '') ?? '' - $: changeOrg(org) function changeOrg(org) { if (value && org) { @@ -30,10 +32,16 @@ } } } + let enabled = $derived(value != undefined) + // Initialize org from existing auth_url + let org = $derived(value?.connect_config?.auth_url?.replace('/application/o/authorize/', '') ?? '') + run(() => { + changeOrg(org) + }); - + + import { run } from 'svelte/legacy'; + import { ExternalLink } from 'lucide-svelte' import OauthScopes from './OauthScopes.svelte' - export let connect_config: { + interface Props { + connect_config?: { scopes: string[] auth_url: string token_url: string req_body_auth: boolean extra_params: { tenant_id: string } extra_params_callback: Record - } = { + }; + } + + let { connect_config = $bindable({ scopes: ['offline_access'], auth_url: '', token_url: '', req_body_auth: true, extra_params: { tenant_id: '' }, extra_params_callback: {} - } + }) }: Props = $props(); - $: if (!connect_config) { - connect_config = { - scopes: ['offline_access'], - auth_url: '', - token_url: '', - req_body_auth: true, - extra_params: { tenant_id: '' }, - extra_params_callback: {} + run(() => { + if (!connect_config) { + connect_config = { + scopes: ['offline_access'], + auth_url: '', + token_url: '', + req_body_auth: true, + extra_params: { tenant_id: '' }, + extra_params_callback: {} + } } - } + }); - $: if (connect_config.extra_params.tenant_id) { - connect_config.auth_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/authorize` - connect_config.token_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/token` - } + run(() => { + if (connect_config.extra_params.tenant_id) { + connect_config.auth_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/authorize` + connect_config.token_url = `https://login.microsoftonline.com/${connect_config.extra_params.tenant_id}/oauth2/v2.0/token` + } + }); diff --git a/frontend/src/lib/components/Badge.svelte b/frontend/src/lib/components/Badge.svelte index 11042b4f1e..8dcad8ef8e 100644 --- a/frontend/src/lib/components/Badge.svelte +++ b/frontend/src/lib/components/Badge.svelte @@ -1,12 +1,22 @@ - + {@render children?.()} {#if tooltip && tooltip != ''} {tooltip} {/if} diff --git a/frontend/src/lib/components/ChangeInstanceUsernameInner.svelte b/frontend/src/lib/components/ChangeInstanceUsernameInner.svelte index 37e3da3d21..6fa87abf64 100644 --- a/frontend/src/lib/components/ChangeInstanceUsernameInner.svelte +++ b/frontend/src/lib/components/ChangeInstanceUsernameInner.svelte @@ -5,12 +5,21 @@ import Alert from './common/alert/Alert.svelte' import { createEventDispatcher } from 'svelte' - export let email: string - export let username: string - export let isConflict = false - export let noPadding = false + interface Props { + email: string; + username: string; + isConflict?: boolean; + noPadding?: boolean; + } - let loading = false + let { + email, + username = $bindable(), + isConflict = false, + noPadding = false + }: Props = $props(); + + let loading = $state(false) let usernameInfo: | { @@ -20,7 +29,7 @@ username: string }[] } - | undefined = undefined + | undefined = $state(undefined) function handleKeyUp(event: KeyboardEvent) { const key = event.key @@ -83,7 +92,7 @@ diff --git a/frontend/src/lib/components/ContextualVariableEditor.svelte b/frontend/src/lib/components/ContextualVariableEditor.svelte index b859e08691..43277787ba 100644 --- a/frontend/src/lib/components/ContextualVariableEditor.svelte +++ b/frontend/src/lib/components/ContextualVariableEditor.svelte @@ -13,25 +13,25 @@ const dispatch = createEventDispatcher() - let edit: boolean = false - let name: string = '' - let value: string = '' + let edit: boolean = $state(false) + let name: string = $state('') + let value: string = $state('') export function initNew(): void { edit = false name = '' value = '' - drawer.openDrawer() + drawer?.openDrawer() } export function editVariable(editName: string, editValue: string): void { edit = true name = editName value = editValue - drawer.openDrawer() + drawer?.openDrawer() } - let drawer: Drawer + let drawer: Drawer | undefined = $state() async function updateVariable(): Promise { await WorkspaceService.setEnvironmentVariable({ @@ -48,7 +48,7 @@ ) dispatch('update') - drawer.closeDrawer() + drawer?.closeDrawer() setTimeout(() => { dispatch('update') }, 5000) @@ -58,7 +58,7 @@ {#if !edit} diff --git a/frontend/src/lib/components/CustomOauth.svelte b/frontend/src/lib/components/CustomOauth.svelte index 8678f46822..bbc020d794 100644 --- a/frontend/src/lib/components/CustomOauth.svelte +++ b/frontend/src/lib/components/CustomOauth.svelte @@ -1,28 +1,32 @@ @@ -42,12 +46,12 @@ bind:value={connect_config.token_url} /> - + Scopes - + Extra Query Args for Authorize Request - + Extra Query Args for Token request Not needed in most cases - + Payload placement) }) const popperOptions: PopperOptions<{}> = { - placement, + placement: untrack(() => placement), strategy: 'fixed', modifiers: [ { name: 'offset', options: { offset: [8, 8] } }, diff --git a/frontend/src/lib/components/CustomSso.svelte b/frontend/src/lib/components/CustomSso.svelte index e11a8d98d8..5c36e1c57e 100644 --- a/frontend/src/lib/components/CustomSso.svelte +++ b/frontend/src/lib/components/CustomSso.svelte @@ -1,10 +1,12 @@ @@ -51,12 +55,12 @@ bind:value={login_config.userinfo_url} /> - + Scopes - + Extra Query Args for Authorize Request - + Extra Query Args for Token request Not needed in most cases - + Payload + import { untrack } from 'svelte' function validate(values: TableEditorValues, dbSchema?: DBSchema) { const columnNamesErrs = values.columns.flatMap((column) => { const isUnique = values.columns.filter((c) => c.name === column.name).length === 1 @@ -92,7 +93,7 @@ computePreview }: Props = $props() - const columnTypes = DB_TYPES[dbType] + const columnTypes = DB_TYPES[untrack(() => dbType)] const defaultColumnType = ( { postgresql: 'BIGSERIAL', @@ -102,10 +103,10 @@ mysql: 'varchar', duckdb: 'string' } satisfies Record - )[dbType] + )[untrack(() => dbType)] const values: TableEditorValues = $state( - $state.snapshot(initialValues) ?? { + $state.snapshot(untrack(() => initialValues)) ?? { name: '', columns: [], foreignKeys: [] @@ -122,8 +123,8 @@ ...(primaryKey && { primaryKey }) }) } - if (!initialValues) { - addColumn({ name: 'id', primaryKey: features?.primaryKeys }) + if (!untrack(() => initialValues)) { + addColumn({ name: 'id', primaryKey: untrack(() => features)?.primaryKeys }) } const errors: ReturnType = $derived(validate(values, dbSchema)) diff --git a/frontend/src/lib/components/DateInput.svelte b/frontend/src/lib/components/DateInput.svelte index d634a149ae..2d1ee73150 100644 --- a/frontend/src/lib/components/DateInput.svelte +++ b/frontend/src/lib/components/DateInput.svelte @@ -69,6 +69,7 @@ let randomId = 'datetarget-' + Math.random().toString(36).substring(7) + + {#if $userStore?.is_admin || $userStore?.is_super_admin} - + diff --git a/frontend/src/lib/components/DefaultScriptsInner.svelte b/frontend/src/lib/components/DefaultScriptsInner.svelte index 6d4979aae1..1a451d8264 100644 --- a/frontend/src/lib/components/DefaultScriptsInner.svelte +++ b/frontend/src/lib/components/DefaultScriptsInner.svelte @@ -6,8 +6,11 @@ import { defaultScriptLanguages } from '$lib/scripts' import Alert from './common/alert/Alert.svelte' - export let small = false - $: langs = computeLangs($defaultScripts) + interface Props { + small?: boolean; + } + + let { small = false }: Props = $props(); function computeLangs(defaultScripts: WorkspaceDefaultScripts | undefined): Script['language'][] { const allLangs = Object.keys(defaultScriptLanguages) as Script['language'][] @@ -30,6 +33,7 @@ requestBody: $defaultScripts }) } + let langs = $derived(computeLangs($defaultScripts)) @@ -47,7 +51,7 @@ {#if i > 0} changePosition(i ?? 0, true)} + onclick={() => changePosition(i ?? 0, true)} class={small ? 'mr-2 text-secondary text-sm' : 'text-lg mr-2'} title="Move up" > @@ -56,7 +60,7 @@ {/if} {#if i < langs.length - 1} changePosition(i ?? 0, false)} + onclick={() => changePosition(i ?? 0, false)} class={small ? 'mr-2 text-secondary text-sm' : 'text-lg mr-2'} title="Move down">↓ diff --git a/frontend/src/lib/components/Description.svelte b/frontend/src/lib/components/Description.svelte index c3cd74c7d6..2078b74cd2 100644 --- a/frontend/src/lib/components/Description.svelte +++ b/frontend/src/lib/components/Description.svelte @@ -2,11 +2,19 @@ import { ExternalLink } from 'lucide-svelte' import { twMerge } from 'tailwind-merge' - export let link: string | undefined = undefined + + interface Props { + link?: string | undefined; + class?: string; + children?: import('svelte').Snippet; + } + + let { link = undefined, class: className = '', children }: Props = $props(); + - - + + {@render children?.()} {#if link} Learn more initial) + if (untrackedInitial) { + if (untrackedInitial.type == 'script') { + replaceScript(untrackedInitial.script) + } else if (untrackedInitial.type == 'flow') { + replaceFlow(untrackedInitial.flow) } modeInitialized = true } @@ -596,9 +597,9 @@ } }) } - let token = $derived($page.url.searchParams.get('wm_token') ?? undefined) - let workspace = $derived($page.url.searchParams.get('workspace') ?? undefined) - let themeDarkRaw = $derived($page.url.searchParams.get('activeColorTheme')) + let token = $derived(page.url.searchParams.get('wm_token') ?? undefined) + let workspace = $derived(page.url.searchParams.get('workspace') ?? undefined) + let themeDarkRaw = $derived(page.url.searchParams.get('activeColorTheme')) let themeDark = $derived(themeDarkRaw == '2' || themeDarkRaw == '4') $effect.pre(() => { diff --git a/frontend/src/lib/components/DropdownSubmenuItem.svelte b/frontend/src/lib/components/DropdownSubmenuItem.svelte index 45346aaa3c..ed08fd7abd 100644 --- a/frontend/src/lib/components/DropdownSubmenuItem.svelte +++ b/frontend/src/lib/components/DropdownSubmenuItem.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/DropdownV2.svelte b/frontend/src/lib/components/DropdownV2.svelte index 902de661aa..c6243f3529 100644 --- a/frontend/src/lib/components/DropdownV2.svelte +++ b/frontend/src/lib/components/DropdownV2.svelte @@ -76,7 +76,7 @@ ids: { menu: dropdownId } } = createDropdownMenu({ positioning: { - placement + placement: untrack(() => placement) }, loop: true, onOpenChange: ({ next }) => { diff --git a/frontend/src/lib/components/DurationMs.svelte b/frontend/src/lib/components/DurationMs.svelte index 451925c0c6..60d2964ffe 100644 --- a/frontend/src/lib/components/DurationMs.svelte +++ b/frontend/src/lib/components/DurationMs.svelte @@ -4,9 +4,13 @@ import { Hourglass } from 'lucide-svelte' import WaitTimeWarning from './common/waitTimeWarning/WaitTimeWarning.svelte' - export let duration_ms: number - export let self_wait_time_ms: number | undefined = undefined - export let aggregate_wait_time_ms: number | undefined = undefined + interface Props { + duration_ms: number; + self_wait_time_ms?: number | undefined; + aggregate_wait_time_ms?: number | undefined; + } + + let { duration_ms, self_wait_time_ms = undefined, aggregate_wait_time_ms = undefined }: Props = $props(); diff --git a/frontend/src/lib/components/DynamicInput.svelte b/frontend/src/lib/components/DynamicInput.svelte index bd6cceaf99..692272d50e 100644 --- a/frontend/src/lib/components/DynamicInput.svelte +++ b/frontend/src/lib/components/DynamicInput.svelte @@ -113,10 +113,10 @@ } }) - let lastArgs = $state.snapshot(otherArgs) + let lastArgs = $state.snapshot(untrack(() => otherArgs)) let timeout: number | undefined = $state() - let nargs = $state($state.snapshot(otherArgs)) + let nargs = $state($state.snapshot(untrack(() => otherArgs))) $effect(() => { otherArgs untrack(() => clearTimeout(timeout)) diff --git a/frontend/src/lib/components/EditableSchemaForm.svelte b/frontend/src/lib/components/EditableSchemaForm.svelte index 99fe00bdb0..989ce6a2fe 100644 --- a/frontend/src/lib/components/EditableSchemaForm.svelte +++ b/frontend/src/lib/components/EditableSchemaForm.svelte @@ -286,7 +286,7 @@ } } - let jsonView: boolean = $state(customUi?.jsonOnly == true) + let jsonView: boolean = $state(untrack(() => customUi)?.jsonOnly == true) let schemaString: string = $state(JSON.stringify(schema, null, '\t')) let error: string | undefined = $state(undefined) let editor: SimpleEditor | undefined = $state(undefined) @@ -296,8 +296,8 @@ editor?.setCode(schemaString) } - const editTabDefaultSize = noPreview ? 100 : 50 - editPanelSize = editTab ? (editPanelInitialSize ?? editTabDefaultSize) : 0 + const editTabDefaultSize = untrack(() => noPreview) ? 100 : 50 + editPanelSize = untrack(() => editTab) ? (untrack(() => editPanelInitialSize) ?? editTabDefaultSize) : 0 let inputPanelSize = $state(100 - editPanelSize) let editPanelSizeSmooth = tweened(editPanelSize, { duration: 150 @@ -592,7 +592,7 @@ {argName} {#if !uiOnly} - + {#snippet trigger()} scriptLang))) - let filePath = $state(computePath(path)) + let filePath = $state(computePath(untrack(() => path))) - let initialPath: string | undefined = $state(path) + let initialPath: string | undefined = $state(untrack(() => path)) let websockets: WebSocket[] = [] let languageClients: MonacoLanguageClient[] = [] @@ -209,7 +209,7 @@ let destroyed = false const uri = computeUri( untrack(() => filePath), - scriptLang + untrack(() => scriptLang) ) console.log('uri', uri) diff --git a/frontend/src/lib/components/ExecutionDuration.svelte b/frontend/src/lib/components/ExecutionDuration.svelte index 9044adff36..0b96607bfe 100644 --- a/frontend/src/lib/components/ExecutionDuration.svelte +++ b/frontend/src/lib/components/ExecutionDuration.svelte @@ -1,32 +1,40 @@ diff --git a/frontend/src/lib/components/FakeMonacoPlaceHolder.svelte b/frontend/src/lib/components/FakeMonacoPlaceHolder.svelte index 3cbc020c9d..c7f068a83f 100644 --- a/frontend/src/lib/components/FakeMonacoPlaceHolder.svelte +++ b/frontend/src/lib/components/FakeMonacoPlaceHolder.svelte @@ -1,6 +1,7 @@ @@ -54,9 +72,11 @@ {#if !emptyString(simpleTooltip)} - - {simpleTooltip} - + {#snippet text()} + + {simpleTooltip} + + {/snippet} {/if} diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte index d3187c43aa..7118719957 100644 --- a/frontend/src/lib/components/FlowBuilder.svelte +++ b/frontend/src/lib/components/FlowBuilder.svelte @@ -228,7 +228,9 @@ } } - const primaryScheduleStore = writable(savedPrimarySchedule) // kept for legacy reasons + const primaryScheduleStore = writable( + untrack(() => savedPrimarySchedule) + ) // kept for legacy reasons const triggersCount = writable(undefined) const simplifiedPoll = writable(false) @@ -601,8 +603,8 @@ const selectionManager = new SelectionManager() const selectedIdStore = $derived(selectionManager.getSelectedId()) // Initialize with selected id if provided - if (selectedId) { - selectionManager.selectId(selectedId) + if (untrack(() => selectedId)) { + selectionManager.selectId(untrack(() => selectedId) ?? '') } else { selectionManager.selectId('settings-metadata') } @@ -611,11 +613,11 @@ return selectedIdStore } - const previewArgsStore = $state({ val: initialArgs }) + const previewArgsStore = $state({ val: untrack(() => initialArgs) }) const scriptEditorDrawer = writable(undefined) const flowEditorDrawer = writable(undefined) - const history = initHistory(flowStore.val) - const pathStore = writable(pathStoreInit ?? initialPath) + const history = initHistory(untrack(() => flowStore).val) + const pathStore = writable(untrack(() => pathStoreInit) ?? initialPath) const captureOn = writable(false) const showCaptureHint = writable(undefined) const flowInputEditorStateStore = writable({ @@ -642,15 +644,15 @@ scriptEditorDrawer, flowEditorDrawer, history, - flowStateStore, - flowStore, + flowStateStore: untrack(() => flowStateStore), + flowStore: untrack(() => flowStore), pathStore, stepsInputArgs, saveDraft, initialPathStore, fakeInitialPath, flowInputsStore: writable({}), - customUi, + customUi: untrack(() => customUi), insertButtonOpen, executionCount: writable(0), flowInputEditorState: flowInputEditorStateStore, @@ -661,10 +663,13 @@ }) // Set up NoteEditor context for note editing capabilities - const noteEditor = new NoteEditor(flowStore, () => { - // Enable notes display when a note is created - flowEditor?.enableNotes?.() - }) + const noteEditor = new NoteEditor( + untrack(() => flowStore), + () => { + // Enable notes display when a note is created + flowEditor?.enableNotes?.() + } + ) setNoteEditorContext(noteEditor) setContext( @@ -678,9 +683,9 @@ [ { type: 'webhook', path: '', isDraft: false }, { type: 'default_email', path: '', isDraft: false }, - ...(draftTriggersFromUrl ?? savedFlow?.draft?.draft_triggers ?? []) + ...(untrack(() => draftTriggersFromUrl) ?? savedFlow?.draft?.draft_triggers ?? []) ], - selectedTriggerIndexFromUrl, + untrack(() => selectedTriggerIndexFromUrl), saveSessionDraft ) ) @@ -804,7 +809,7 @@ onClick: () => void }> = [] - if (customUi.topBar?.extraDeployOptions != false) { + if (untrack(() => customUi).topBar?.extraDeployOptions != false) { if (savedFlow?.draft_only === false || savedFlow?.draft_only === undefined) { dropdownItems.push({ label: 'Exit & see details', @@ -812,14 +817,14 @@ }) } - if (!newFlow) { + if (!untrack(() => newFlow)) { dropdownItems.push({ label: 'Fork', onClick: () => window.open(`/flows/add?template=${initialPath}`) }) } - if (!newFlow && !isCloudHosted() && !isRuleActive('DisableWorkspaceForking')) { + if (!untrack(() => newFlow) && !isCloudHosted() && !isRuleActive('DisableWorkspaceForking')) { dropdownItems.push({ label: 'Edit in workspace fork', onClick: () => window.open(buildForkEditUrl('flow', initialPath)) @@ -1036,10 +1041,10 @@ } let stepHistoryLoader = new StepHistoryLoader( - loadedFromHistoryFromUrl?.stepsState ?? {}, - loadedFromHistoryFromUrl?.flowJobInitial, + untrack(() => loadedFromHistoryFromUrl)?.stepsState ?? {}, + untrack(() => loadedFromHistoryFromUrl)?.flowJobInitial, saveSessionDraft, - noInitial + untrack(() => noInitial) ) setStepHistoryLoaderContext(stepHistoryLoader) diff --git a/frontend/src/lib/components/FlowGraphViewer.svelte b/frontend/src/lib/components/FlowGraphViewer.svelte index 35c21cb261..f4b3b1cc97 100644 --- a/frontend/src/lib/components/FlowGraphViewer.svelte +++ b/frontend/src/lib/components/FlowGraphViewer.svelte @@ -9,23 +9,38 @@ import { dfs } from './flows/dfs' import { workspaceStore } from '$lib/stores' - export let flow: { + + interface Props { + flow: { summary: string description?: string value: FlowValue schema?: any path?: string + }; + overflowAuto?: boolean; + noSide?: boolean; + download?: boolean; + noGraph?: boolean; + triggerNode?: boolean; + stepDetail?: FlowModule | string | undefined; + workspace?: string | undefined; + minHeight?: number; + noBorder?: boolean; } - export let overflowAuto = false - export let noSide = false - export let download = false - export let noGraph = false - export let triggerNode = false - export let stepDetail: FlowModule | string | undefined = undefined - export let workspace: string | undefined = $workspaceStore - export let minHeight = 400 - export let noBorder = false + let { + flow, + overflowAuto = false, + noSide = false, + download = false, + noGraph = false, + triggerNode = false, + stepDetail = $bindable(undefined), + workspace = $workspaceStore, + minHeight = 400, + noBorder = false + }: Props = $props(); const dispatch = createEventDispatcher() diff --git a/frontend/src/lib/components/FlowGraphViewerStep.svelte b/frontend/src/lib/components/FlowGraphViewerStep.svelte index 81d15843d8..8c560abef0 100644 --- a/frontend/src/lib/components/FlowGraphViewerStep.svelte +++ b/frontend/src/lib/components/FlowGraphViewerStep.svelte @@ -19,17 +19,20 @@ import HighlightTheme from './HighlightTheme.svelte' import LanguageIcon from './common/languageIcons/LanguageIcon.svelte' - export let schema: any | undefined = undefined + interface Props { + schema?: any | undefined + stepDetail?: FlowModule | string | undefined + jobScriptHash?: string | undefined + } - export let stepDetail: FlowModule | string | undefined = undefined - export let jobScriptHash: string | undefined = undefined - let codeViewer: Drawer + let { schema = undefined, stepDetail = undefined, jobScriptHash = undefined }: Props = $props() + let codeViewer: Drawer | undefined = $state() - + {#if stepDetail && typeof stepDetail != 'string'} {#if stepDetail.value.type == 'script'} @@ -183,7 +186,7 @@ Expand @@ -221,7 +224,7 @@ Expand diff --git a/frontend/src/lib/components/FlowInputViewer.svelte b/frontend/src/lib/components/FlowInputViewer.svelte index 94c25ffcc4..62aef2dd37 100644 --- a/frontend/src/lib/components/FlowInputViewer.svelte +++ b/frontend/src/lib/components/FlowInputViewer.svelte @@ -3,7 +3,11 @@ import FieldHeader from './FieldHeader.svelte' - export let schema: Schema | { [key: string]: unknown } | undefined + interface Props { + schema: Schema | { [key: string]: unknown } | undefined; + } + + let { schema }: Props = $props(); diff --git a/frontend/src/lib/components/FlowLogViewerWrapper.svelte b/frontend/src/lib/components/FlowLogViewerWrapper.svelte index 4549fc8304..648dbc9f06 100644 --- a/frontend/src/lib/components/FlowLogViewerWrapper.svelte +++ b/frontend/src/lib/components/FlowLogViewerWrapper.svelte @@ -62,7 +62,7 @@ const timelineItems = $derived(timelineCompute?.items ?? undefined) const timelineNow = $derived(timelineCompute?.now ?? Date.now()) - let moduleTracker = new ChangeTracker($state.snapshot(job.raw_flow?.modules ?? [])) + let moduleTracker = new ChangeTracker($state.snapshot(untrack(() => job).raw_flow?.modules ?? [])) $effect(() => { readFieldsRecursively(job.raw_flow?.modules ?? []) untrack(() => moduleTracker.track($state.snapshot(job.raw_flow?.modules ?? []))) @@ -123,7 +123,7 @@ } let timelineAvailableWidths = $state>({}) - let lastJobId: string | undefined = $state(job.id) + let lastJobId: string | undefined = $state(untrack(() => job).id) const timelinelWidth = $derived.by(() => { const widths = Object.values(timelineAvailableWidths) diff --git a/frontend/src/lib/components/FlowPlugConnect.svelte b/frontend/src/lib/components/FlowPlugConnect.svelte index da70d882db..cd44f3d1bd 100644 --- a/frontend/src/lib/components/FlowPlugConnect.svelte +++ b/frontend/src/lib/components/FlowPlugConnect.svelte @@ -4,9 +4,13 @@ import AnimatedButton from './common/button/AnimatedButton.svelte' import { twMerge } from 'tailwind-merge' - export let connecting: boolean - export let id: undefined | string = undefined - export let wrapperClasses = '' + interface Props { + connecting: boolean; + id?: undefined | string; + wrapperClasses?: string; + } + + let { connecting, id = undefined, wrapperClasses = '' }: Props = $props(); diff --git a/frontend/src/lib/components/FlowStatusViewer.svelte b/frontend/src/lib/components/FlowStatusViewer.svelte index 5da8b31419..950eb7354f 100644 --- a/frontend/src/lib/components/FlowStatusViewer.svelte +++ b/frontend/src/lib/components/FlowStatusViewer.svelte @@ -62,7 +62,7 @@ showLogsWithResult = false }: Props = $props() - let lastJobId: string = jobId + let lastJobId: string = untrack(() => jobId) let retryStatus = $state({ val: {} }) let globalRefreshes: Record Promise)[]> = $state({}) @@ -71,11 +71,11 @@ flowState, suspendStatus, retryStatus, - hideDownloadInGraph, - hideNodeDefinition, - hideTimeline, - hideJobId, - hideDownloadLogs + hideDownloadInGraph: untrack(() => hideDownloadInGraph), + hideNodeDefinition: untrack(() => hideNodeDefinition), + hideTimeline: untrack(() => hideTimeline), + hideJobId: untrack(() => hideJobId), + hideDownloadLogs: untrack(() => hideDownloadLogs) }) function loadOwner(path: string) { diff --git a/frontend/src/lib/components/FlowStatusViewerInner.svelte b/frontend/src/lib/components/FlowStatusViewerInner.svelte index 410ba822ab..25731f82c8 100644 --- a/frontend/src/lib/components/FlowStatusViewerInner.svelte +++ b/frontend/src/lib/components/FlowStatusViewerInner.svelte @@ -181,7 +181,7 @@ let resultStreams: Record = $state({}) - if (onResultStreamUpdate == undefined) { + if (untrack(() => onResultStreamUpdate) == undefined) { onResultStreamUpdate = ({ jobId, result_stream @@ -234,7 +234,7 @@ }) let jobResults: any[] = $state( - flowJobIds?.flowJobs?.map((x, id) => `iter #${id + 1} not loaded by frontend yet`) ?? [] + untrack(() => flowJobIds)?.flowJobs?.map((x, id) => `iter #${id + 1} not loaded by frontend yet`) ?? [] ) let retry_selected = $state('') @@ -805,7 +805,7 @@ let destroyed = false - updateRecursiveRefresh(jobId) + updateRecursiveRefresh(untrack(() => jobId)) async function updateJobId() { if (jobId !== job?.id || innerModules == undefined) { diff --git a/frontend/src/lib/components/FlowViewer.svelte b/frontend/src/lib/components/FlowViewer.svelte index 8a78637519..2355ddf68d 100644 --- a/frontend/src/lib/components/FlowViewer.svelte +++ b/frontend/src/lib/components/FlowViewer.svelte @@ -1,4 +1,5 @@ {#if tabular} diff --git a/frontend/src/lib/components/GraphqlSchemaViewer.svelte b/frontend/src/lib/components/GraphqlSchemaViewer.svelte index 7929083d9a..1ab4c68f00 100644 --- a/frontend/src/lib/components/GraphqlSchemaViewer.svelte +++ b/frontend/src/lib/components/GraphqlSchemaViewer.svelte @@ -5,10 +5,17 @@ import { onDestroy, onMount } from 'svelte' - let divEl: HTMLDivElement | null = null + let divEl: HTMLDivElement | null = $state(null) let editor: meditor.IStandaloneCodeEditor - export let code: string = '' + + interface Props { + code?: string; + class?: string; + } + + let { code = '', class: className = '' }: Props = $props(); + async function loadMonaco() { editor = meditor.create(divEl as HTMLDivElement, { @@ -43,4 +50,4 @@ }) - + diff --git a/frontend/src/lib/components/GroupEditor.svelte b/frontend/src/lib/components/GroupEditor.svelte index a8391bd8a6..5a8c4cb411 100644 --- a/frontend/src/lib/components/GroupEditor.svelte +++ b/frontend/src/lib/components/GroupEditor.svelte @@ -159,12 +159,14 @@ {/if} {#if members} - - - user - - - + + {#snippet headerRow()} + + user + + + + {/snippet} {#snippet body()} {#each members ?? [] as { member_name, role }} @@ -301,10 +303,12 @@ {#if instance_group?.emails} Members from the instance group - - - user - + + {#snippet headerRow()} + + user + + {/snippet} {#snippet body()} {#each instance_group?.emails ?? [] as email} diff --git a/frontend/src/lib/components/IdEditorInput.svelte b/frontend/src/lib/components/IdEditorInput.svelte index 7b85d8e52b..611dbc2d3e 100644 --- a/frontend/src/lib/components/IdEditorInput.svelte +++ b/frontend/src/lib/components/IdEditorInput.svelte @@ -1,4 +1,5 @@ {#if entries.length} diff --git a/frontend/src/lib/components/InstanceGroupEditor.svelte b/frontend/src/lib/components/InstanceGroupEditor.svelte index cf2a3ded0a..f3d8df33de 100644 --- a/frontend/src/lib/components/InstanceGroupEditor.svelte +++ b/frontend/src/lib/components/InstanceGroupEditor.svelte @@ -1,4 +1,6 @@ @@ -85,17 +91,20 @@ {#if members} - - user - - - - {#each members as { member_email }} - {member_email} - - { + {#snippet headerRow()} + + user + + + {/snippet} + {#snippet body()} + + {#each members as { member_email }} + {member_email} + + { await GroupService.removeUserFromInstanceGroup({ name, requestBody: { email: member_email } @@ -104,10 +113,11 @@ sendUserToast('User removed') loadInstanceGroup() }}>remove - - {/each} - + > + + {/each} + + {/snippet} {:else} diff --git a/frontend/src/lib/components/InstanceNameEditor.svelte b/frontend/src/lib/components/InstanceNameEditor.svelte index 31fc3d738b..cb710cddce 100644 --- a/frontend/src/lib/components/InstanceNameEditor.svelte +++ b/frontend/src/lib/components/InstanceNameEditor.svelte @@ -1,4 +1,7 @@ - + {'REALM_URL/protocol/openid-connect/auth'} - + Custom Name diff --git a/frontend/src/lib/components/LogId.svelte b/frontend/src/lib/components/LogId.svelte index bb90a700cf..cadbe14e0c 100644 --- a/frontend/src/lib/components/LogId.svelte +++ b/frontend/src/lib/components/LogId.svelte @@ -1,5 +1,13 @@ diff --git a/frontend/src/lib/components/LogSnippetViewer.svelte b/frontend/src/lib/components/LogSnippetViewer.svelte index 1781351573..8aa1ad9dec 100644 --- a/frontend/src/lib/components/LogSnippetViewer.svelte +++ b/frontend/src/lib/components/LogSnippetViewer.svelte @@ -1,8 +1,14 @@ - + {@html html} diff --git a/frontend/src/lib/components/LogViewer.svelte b/frontend/src/lib/components/LogViewer.svelte index 0118c32cb8..a62827bba2 100644 --- a/frontend/src/lib/components/LogViewer.svelte +++ b/frontend/src/lib/components/LogViewer.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/MemoryFootprintViewer.svelte b/frontend/src/lib/components/MemoryFootprintViewer.svelte index 66da99e6e6..9547861bc3 100644 --- a/frontend/src/lib/components/MemoryFootprintViewer.svelte +++ b/frontend/src/lib/components/MemoryFootprintViewer.svelte @@ -1,4 +1,6 @@ diff --git a/frontend/src/lib/components/ModuleStatus.svelte b/frontend/src/lib/components/ModuleStatus.svelte index 36f7b54753..351b3e0d03 100644 --- a/frontend/src/lib/components/ModuleStatus.svelte +++ b/frontend/src/lib/components/ModuleStatus.svelte @@ -5,9 +5,13 @@ import { displayDate } from '$lib/utils' import { Hourglass } from 'lucide-svelte' - export let type: FlowStatusModule['type'] - export let scheduled_for: Date | undefined - export let skipped: boolean = false + interface Props { + type: FlowStatusModule['type']; + scheduled_for: Date | undefined; + skipped?: boolean; + } + + let { type, scheduled_for, skipped = false }: Props = $props(); {#if type == 'WaitingForEvents'} diff --git a/frontend/src/lib/components/ModuleTest.svelte b/frontend/src/lib/components/ModuleTest.svelte index 59c8f973ea..37cb96bea7 100644 --- a/frontend/src/lib/components/ModuleTest.svelte +++ b/frontend/src/lib/components/ModuleTest.svelte @@ -8,7 +8,7 @@ } from '$lib/gen' import { workspaceStore } from '$lib/stores' import { getScriptByPath } from '$lib/scripts' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import type { FlowEditorContext } from './flows/types' import JobLoader, { type Callbacks } from './JobLoader.svelte' import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte' @@ -167,8 +167,8 @@ testJob = modulesTestStates.states?.[mod.id]?.testJob }) - modulesTestStates.states[mod.id] = { - ...(modulesTestStates.states?.[mod.id] ?? { loading: false }), + modulesTestStates.states[untrack(() => mod).id] = { + ...(modulesTestStates.states?.[untrack(() => mod).id] ?? { loading: false }), loading: testIsLoading, testJob: testJob } diff --git a/frontend/src/lib/components/OauthExtraParams.svelte b/frontend/src/lib/components/OauthExtraParams.svelte index 826f0237af..eec9cd47b8 100644 --- a/frontend/src/lib/components/OauthExtraParams.svelte +++ b/frontend/src/lib/components/OauthExtraParams.svelte @@ -2,9 +2,13 @@ import { Button } from './common' import { X, Plus } from 'lucide-svelte' - export let extra_params: Record = {} + interface Props { + extra_params?: Record; + } - let extra_params_vec: [string, string][] = Object.entries(extra_params) + let { extra_params = $bindable({}) }: Props = $props(); + + let extra_params_vec: [string, string][] = $state(Object.entries(extra_params)) function sync() { extra_params = Object.fromEntries(extra_params_vec) @@ -13,8 +17,8 @@ {#each extra_params_vec as o} - - + + {#if scopes && Array.isArray(scopes)} - {#each scopes as v} + {#each scopes as v, i} - + e.detail && loadUsers()}> - - - - {#if selectedDisplayName} - {selectedDisplayName} + {#snippet trigger()} + + + + {#if selectedDisplayName} + {selectedDisplayName} + {/if} + + + {/snippet} + {#snippet content({ close: closePopover })} + + {label} + + {#if targetEmail} + onSelect('target')} + > + + {targetUsername} + {isDeployment ? '(target)' : '(current)'} + {/if} - - - - {label} - - {#if targetEmail} + + onSelect('me')} + > + + {$userStore?.username} + (me) + + onSelect('target')} + onclick={() => { + closePopover() + openModal() + }} > - - {targetUsername} - {isDeployment ? '(target)' : '(current)'} + {#if selected === 'custom' && customUsername} + + {customUsername} + (custom) + {:else} + + + Pick from workspace… + {/if} - {/if} - - onSelect('me')} - > - - {$userStore?.username} - (me) - - - { - closePopover() - openModal() - }} - > - {#if selected === 'custom' && customUsername} - - {customUsername} - (custom) - {:else} - - - Pick from workspace… - {/if} - - + + {/snippet} diff --git a/frontend/src/lib/components/PageHeader.svelte b/frontend/src/lib/components/PageHeader.svelte index 07b02227d4..556ac1b0cc 100644 --- a/frontend/src/lib/components/PageHeader.svelte +++ b/frontend/src/lib/components/PageHeader.svelte @@ -1,11 +1,23 @@ @@ -31,9 +43,9 @@ {/if} - {#if $$slots.default} + {#if children} - + {@render children?.()} {/if} diff --git a/frontend/src/lib/components/ParqetCsvTableRenderer.svelte b/frontend/src/lib/components/ParqetCsvTableRenderer.svelte index 07a8c267a9..262be32363 100644 --- a/frontend/src/lib/components/ParqetCsvTableRenderer.svelte +++ b/frontend/src/lib/components/ParqetCsvTableRenderer.svelte @@ -1,4 +1,6 @@ @@ -182,7 +189,7 @@ Separator - mountGrid()}> + mountGrid()}> , ; \t diff --git a/frontend/src/lib/components/PermissionHistory.svelte b/frontend/src/lib/components/PermissionHistory.svelte index 82d646bd53..23f3ec151f 100644 --- a/frontend/src/lib/components/PermissionHistory.svelte +++ b/frontend/src/lib/components/PermissionHistory.svelte @@ -79,12 +79,14 @@ No permission changes recorded yet {:else} - - Changed By - Change Type - Affected - Date - + {#snippet headerRow()} + + Changed By + Change Type + Affected + Date + + {/snippet} {#snippet body()} {#each history as change} diff --git a/frontend/src/lib/components/PersistentScriptDrawer.svelte b/frontend/src/lib/components/PersistentScriptDrawer.svelte index aa5c869f31..23fa122b7d 100644 --- a/frontend/src/lib/components/PersistentScriptDrawer.svelte +++ b/frontend/src/lib/components/PersistentScriptDrawer.svelte @@ -10,19 +10,19 @@ import { Hourglass, Loader2, Play, RefreshCw } from 'lucide-svelte' let dispatch = createEventDispatcher() - let drawer: Drawer + let drawer: Drawer | undefined = $state() - let script: Script - let loadQueuedJobs = true - let queuedJobsLoading = false + let script: Script | undefined = $state() + let loadQueuedJobs = $state(true) + let queuedJobsLoading = $state(false) let queuedJobs: { status: 'running' | 'queued' jobId: string scheduledFor: string scriptHash: string - }[] = [] + }[] = $state([]) - let cancellingInProgress = false + let cancellingInProgress = $state(false) async function continuouslyLoadQueuedJobs() { while (loadQueuedJobs) { @@ -40,7 +40,7 @@ let qjs = await JobService.listQueue({ workspace: $workspaceStore ?? '', orderDesc: false, - scriptPathExact: script.path + scriptPathExact: script?.path }) let loadingQueuedJobs: { status: 'running' | 'queued' @@ -71,12 +71,12 @@ cancellingInProgress = true await JobService.cancelPersistentQueuedJobs({ workspace: $workspaceStore ?? '', - path: script.path, + path: script?.path ?? '', requestBody: { reason: undefined } }) - sendUserToast(`All jobs cancelled for ${script.path}`) + sendUserToast(`All jobs cancelled for ${script?.path}`) cancellingInProgress = false } @@ -88,12 +88,12 @@ script = persistentScript! loadQueuedJobs = true continuouslyLoadQueuedJobs() - drawer.openDrawer?.() + drawer?.openDrawer?.() } async function exit() { loadQueuedJobs = false - drawer.closeDrawer?.() + drawer?.closeDrawer?.() } onDestroy(() => { @@ -117,51 +117,57 @@ > - Queued jobs for {script.path} + Queued jobs for {script?.path} - - Script Hash - Job ID - Status - Scheduled For - - - {#each queuedJobs as { jobId, status, scriptHash, scheduledFor }} - - - - {scriptHash} - - - - {jobId.substring(24)} - - - {#if status === 'running'} - - - - {:else} - - - - {/if} - - {scheduledFor} - - {/each} - + {#snippet headerRow()} + + Script Hash + Job ID + Status + Scheduled For + + {/snippet} + {#snippet body()} + + {#each queuedJobs as { jobId, status, scriptHash, scheduledFor }} + + + + {scriptHash} + + + + {jobId.substring(24)} + + + {#if status === 'running'} + + + + {:else} + + + + {/if} + + {scheduledFor} + + {/each} + + {/snippet} {#snippet actions()} diff --git a/frontend/src/lib/components/Popover.svelte b/frontend/src/lib/components/Popover.svelte index 1fa0a0d88d..07447b2e4a 100644 --- a/frontend/src/lib/components/Popover.svelte +++ b/frontend/src/lib/components/Popover.svelte @@ -43,10 +43,10 @@ onClick }: Props = $props() - const [popperRef, popperContent] = createPopperActions({ placement }) + const [popperRef, popperContent] = createPopperActions({ placement: untrack(() => placement) }) const popperOptions: PopperOptions<{}> = { - placement, + placement: untrack(() => placement), strategy: 'fixed', modifiers: [ { name: 'offset', options: { offset: [8, 8] } }, diff --git a/frontend/src/lib/components/PrefixedInput.svelte b/frontend/src/lib/components/PrefixedInput.svelte index c548418855..2a1dccf386 100644 --- a/frontend/src/lib/components/PrefixedInput.svelte +++ b/frontend/src/lib/components/PrefixedInput.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/RadioButton.svelte b/frontend/src/lib/components/RadioButton.svelte index efa9a62b40..c7e5dc8dce 100644 --- a/frontend/src/lib/components/RadioButton.svelte +++ b/frontend/src/lib/components/RadioButton.svelte @@ -1,13 +1,24 @@ @@ -28,7 +39,7 @@ class="sr-only" bind:group={value} aria-labelledby="memory-option-0-label" - on:click={() => dispatch('change', val)} + onclick={() => dispatch('change', val)} /> {#if typeof label !== 'string'} diff --git a/frontend/src/lib/components/Range.svelte b/frontend/src/lib/components/Range.svelte index 0e92ac72de..72129aada2 100644 --- a/frontend/src/lib/components/Range.svelte +++ b/frontend/src/lib/components/Range.svelte @@ -1,29 +1,47 @@ - + {#if max <= min} Impossible to display range: {`max (${max}) <= min (${min})`} + import { untrack } from 'svelte' import { GitSyncService } from '$lib/gen' import Select from './select/Select.svelte' @@ -32,7 +33,7 @@ }: Props = $props() // Track all loaded repositories across pages - let loadedRepositories = $state(initialRepositories) + let loadedRepositories = $state(untrack(() => initialRepositories)) let currentPage = $state(1) let isLoadingMore = $state(false) diff --git a/frontend/src/lib/components/Required.svelte b/frontend/src/lib/components/Required.svelte index 2163efa976..3ee1deec1a 100644 --- a/frontend/src/lib/components/Required.svelte +++ b/frontend/src/lib/components/Required.svelte @@ -1,12 +1,19 @@ {#if required} - * + * {:else if detail || detail != ''} - ({detail != '' ? `${detail}` : ''}) {/if} diff --git a/frontend/src/lib/components/ResourceEditor.svelte b/frontend/src/lib/components/ResourceEditor.svelte index 0ffed949d1..70aaf6a2ee 100644 --- a/frontend/src/lib/components/ResourceEditor.svelte +++ b/frontend/src/lib/components/ResourceEditor.svelte @@ -30,7 +30,6 @@ canSave?: boolean resource_type?: string | undefined path?: string - newResource?: boolean hidePath?: boolean onChange?: (args: { path: string; args: Record; description: string }) => void defaultValues?: Record | undefined @@ -40,7 +39,6 @@ canSave = $bindable(true), resource_type = $bindable(undefined), path = $bindable(''), - newResource = false, hidePath = false, onChange, defaultValues = undefined @@ -63,6 +61,7 @@ let resourceTypeInfo: ResourceType | undefined = $state(undefined) let editDescription = $state(false) let viewJsonSchema = $state(false) + let newResource = $derived(!path) const dispatch = createEventDispatcher() @@ -82,7 +81,7 @@ .map(([k, _]) => k) } - if (!newResource) { + if (!untrack(() => newResource)) { initEdit() } else if (resource_type) { loadResourceType() diff --git a/frontend/src/lib/components/ResourceEditorDrawer.svelte b/frontend/src/lib/components/ResourceEditorDrawer.svelte index 50db916f13..dae6943868 100644 --- a/frontend/src/lib/components/ResourceEditorDrawer.svelte +++ b/frontend/src/lib/components/ResourceEditorDrawer.svelte @@ -5,50 +5,44 @@ import { Loader2, Save } from 'lucide-svelte' - let drawer: Drawer - let canSave = true - let resource_type: string | undefined = undefined - let defaultValues: Record | undefined = undefined + let drawer: Drawer | undefined = $state() + let canSave = $state(true) + let resource_type: string | undefined = $state(undefined) + let defaultValues: Record | undefined = $state(undefined) let resourceEditor: { editResource: () => void; createResource: () => void } | undefined = - undefined + $state(undefined) - let path: string | undefined = undefined + let path: string | undefined = $state(undefined) - let newResource = false export async function initEdit(p: string): Promise { resource_type = undefined - newResource = false path = p - drawer.openDrawer?.() + drawer?.openDrawer?.() } export async function initNew( resourceType: string, nDefaultValues?: Record ): Promise { - newResource = true path = undefined resource_type = resourceType defaultValues = nDefaultValues - drawer.openDrawer?.() + drawer?.openDrawer?.() } - let mode: 'edit' | 'new' = newResource ? 'new' : 'edit' - - $: path ? (mode = 'edit') : (mode = 'new') + let mode: 'edit' | 'new' = $derived(!path ? 'new' : 'edit') {#await import('./ResourceEditor.svelte')} {:then Module} diff --git a/frontend/src/lib/components/ResourcePicker.svelte b/frontend/src/lib/components/ResourcePicker.svelte index 6806e60d3c..fddf9205f5 100644 --- a/frontend/src/lib/components/ResourcePicker.svelte +++ b/frontend/src/lib/components/ResourcePicker.svelte @@ -152,7 +152,7 @@ loading = false } - let previousResourceType = resourceType + let previousResourceType = untrack(() => resourceType) $effect(() => { $workspaceStore && resourceType diff --git a/frontend/src/lib/components/RunForm.svelte b/frontend/src/lib/components/RunForm.svelte index 969576a06b..da0c87a15f 100644 --- a/frontend/src/lib/components/RunForm.svelte +++ b/frontend/src/lib/components/RunForm.svelte @@ -15,7 +15,7 @@ import Popover from './meltComponents/Popover.svelte' import { Calendar, Check, CornerDownLeft } from 'lucide-svelte' import RunFormAdvancedPopup from './RunFormAdvancedPopup.svelte' - import { page } from '$app/stores' + import { page } from '$app/state' import { replaceState } from '$app/navigation' import JsonInputs from '$lib/components/JsonInputs.svelte' import { triggerableByAI } from '$lib/actions/triggerableByAI.svelte' @@ -108,7 +108,7 @@ nurl.hash = computeSharableHash(args) try { - replaceState(nurl.toString(), $page.state) + replaceState(nurl.toString(), page.state) } catch (e) { console.error(e) } diff --git a/frontend/src/lib/components/RunFormAdvancedPopup.svelte b/frontend/src/lib/components/RunFormAdvancedPopup.svelte index 7d6ef01bb2..399e55f772 100644 --- a/frontend/src/lib/components/RunFormAdvancedPopup.svelte +++ b/frontend/src/lib/components/RunFormAdvancedPopup.svelte @@ -8,7 +8,9 @@ import { WorkerService } from '$lib/gen' import DateTimeInput from './DateTimeInput.svelte' - export let runnable: + + interface Props { + runnable: | { summary?: string description?: string @@ -21,11 +23,18 @@ created_by?: string extra_perms?: Record } - | undefined + | undefined; + scheduledForStr: string | undefined; + invisible_to_owner: boolean | undefined; + overrideTag: string | undefined; + } - export let scheduledForStr: string | undefined - export let invisible_to_owner: boolean | undefined - export let overrideTag: string | undefined + let { + runnable, + scheduledForStr = $bindable(), + invisible_to_owner = $bindable(), + overrideTag = $bindable() + }: Props = $props(); loadWorkerGroups() async function loadWorkerGroups() { diff --git a/frontend/src/lib/components/RunsPage.svelte b/frontend/src/lib/components/RunsPage.svelte index d03495c052..5aee359a4a 100644 --- a/frontend/src/lib/components/RunsPage.svelte +++ b/frontend/src/lib/components/RunsPage.svelte @@ -96,8 +96,8 @@ let batchRerunOptionsIsOpen = $state(false) // Initialize path filter from route param if provided and not already set via query params - if (initialPath && !filters.val.path) { - filters.val.path = initialPath + if (untrack(() => initialPath) && !filters.val.path) { + filters.val.path = untrack(() => initialPath) } // Apply persistent toggle values from local storage if URL doesn't specify them diff --git a/frontend/src/lib/components/S3ObjectPicker.svelte b/frontend/src/lib/components/S3ObjectPicker.svelte index c70983ee83..1c461708cd 100644 --- a/frontend/src/lib/components/S3ObjectPicker.svelte +++ b/frontend/src/lib/components/S3ObjectPicker.svelte @@ -11,15 +11,19 @@ import S3FilePicker from './S3FilePicker.svelte' import FileUpload from './common/fileUpload/FileUpload.svelte' - export let value: any - export let editor: SimpleEditor | undefined = undefined + interface Props { + value: any + editor?: SimpleEditor | undefined + } + + let { value = $bindable(), editor = $bindable(undefined) }: Props = $props() const dispatch = createEventDispatcher() - let s3FilePicker: S3FilePicker - let s3FileUploadRawMode: false + let s3FilePicker: S3FilePicker | undefined = $state() + let s3FileUploadRawMode: boolean | undefined = $state() let el: HTMLTextAreaElement | undefined = undefined - let rawValue: string | undefined = undefined + let rawValue: string | undefined = $state(undefined) function evalValueToRaw() { rawValue = JSON.stringify(value, null, 2) diff --git a/frontend/src/lib/components/SaveInputsButton.svelte b/frontend/src/lib/components/SaveInputsButton.svelte index 414e5ff205..4bddde54ca 100644 --- a/frontend/src/lib/components/SaveInputsButton.svelte +++ b/frontend/src/lib/components/SaveInputsButton.svelte @@ -10,14 +10,25 @@ const dispatch = createEventDispatcher() - export let runnableId: string | undefined - export let runnableType: RunnableType | undefined - export let args: object - export let disabled: boolean = false - export let small: boolean | undefined = undefined - export let showTooltip: boolean | undefined = undefined + interface Props { + runnableId: string | undefined; + runnableType: RunnableType | undefined; + args: object; + disabled?: boolean; + small?: boolean | undefined; + showTooltip?: boolean | undefined; + } - let savingInputs = false + let { + runnableId, + runnableType, + args, + disabled = false, + small = undefined, + showTooltip = undefined + }: Props = $props(); + + let savingInputs = $state(false) async function saveInput(args: object) { savingInputs = true diff --git a/frontend/src/lib/components/SavedInputsPickerViewer.svelte b/frontend/src/lib/components/SavedInputsPickerViewer.svelte index 150e2b9b97..f033bbf4d9 100644 --- a/frontend/src/lib/components/SavedInputsPickerViewer.svelte +++ b/frontend/src/lib/components/SavedInputsPickerViewer.svelte @@ -1,20 +1,34 @@ - + {#snippet trigger({ isOpen })} - - + {/snippet} + {#snippet content()} { + onclick={() => { copyToClipboard(JSON.stringify(payloadData)) }} - on:keydown + onkeydown={bubble('keydown')} > {#if !objectViewerLoaded && payloadTooBigForPreview} @@ -158,5 +174,5 @@ {/if} - + {/snippet} diff --git a/frontend/src/lib/components/SchemaEditorProperty.svelte b/frontend/src/lib/components/SchemaEditorProperty.svelte index 611e178981..fa12138c0d 100644 --- a/frontend/src/lib/components/SchemaEditorProperty.svelte +++ b/frontend/src/lib/components/SchemaEditorProperty.svelte @@ -2,7 +2,11 @@ import type { SchemaProperty } from '$lib/common' import Badge from './common/badge/Badge.svelte' - export let property: SchemaProperty + interface Props { + property: SchemaProperty; + } + + let { property }: Props = $props(); diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 3de7ad3895..e4e166791b 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -157,7 +157,7 @@ let deployedBy: string | undefined = $state(undefined) // Author let confirmCallback: () => void = $state(() => {}) // What happens when user clicks `override` in warning let open: boolean = $state(false) // Is confirmation modal open - let args: Record = $state(initialArgs) // Test args input + let args: Record = $state(untrack(() => initialArgs)) // Test args input let selectedInputTab: 'main' | 'preprocessor' = $state('main') let hasPreprocessor = $state(false) let preserveOnBehalfOf = $state(false) @@ -170,12 +170,12 @@ let customOnBehalfOfEmail: string = $state('') let metadataOpen = $state( - !neverShowMeta && - (showMeta || - searchParams.get('metadata_open') == 'true' || + !untrack(() => neverShowMeta) && + (untrack(() => showMeta) || + untrack(() => searchParams).get('metadata_open') == 'true' || (initialPath == '' && - searchParams.get('state') == undefined && - searchParams.get('collab') == undefined)) + untrack(() => searchParams).get('state') == undefined && + untrack(() => searchParams).get('collab') == undefined)) ) let editor: Editor | undefined = $state(undefined) @@ -193,10 +193,15 @@ confirmDeploymentCallback(selectedTriggers) } - const primaryScheduleStore = writable(savedPrimarySchedule) // keep for legacy + const primaryScheduleStore = writable( + untrack(() => savedPrimarySchedule) + ) // keep for legacy const triggersCount = writable( - savedPrimarySchedule - ? { schedule_count: 1, primary_schedule: { schedule: savedPrimarySchedule.cron } } + untrack(() => savedPrimarySchedule) + ? { + schedule_count: 1, + primary_schedule: { schedule: untrack(() => savedPrimarySchedule)!.cron } + } : undefined ) const simplifiedPoll = writable(false) @@ -859,7 +864,7 @@ })() ) - setContext('disableTooltips', customUi?.disableTooltips === true) + setContext('disableTooltips', untrack(() => customUi)?.disableTooltips === true) function langToLanguage(lang: SupportedLanguage | 'docker' | 'bunnative'): SupportedLanguage { if (lang == 'docker') { @@ -1672,8 +1677,10 @@ /> {:else if script.on_behalf_of_email && !canPreserve} - Currently: {originalOnBehalfOfEmail ?? script.on_behalf_of_email}. - Will be set to {$userStore?.email} on deploy (requires admin or wm_deployers group to override) + Currently: {originalOnBehalfOfEmail ?? script.on_behalf_of_email}. Will be set to {$userStore?.email} on + deploy (requires admin or wm_deployers group to override) {/if} diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte index 0f1e1d8a6e..f310010c18 100644 --- a/frontend/src/lib/components/ScriptEditor.svelte +++ b/frontend/src/lib/components/ScriptEditor.svelte @@ -123,7 +123,7 @@ lastDeployedCode?: string | undefined disableAi?: boolean assets?: AssetWithAltAccessType[] - editor_bar_right?: import('svelte').Snippet + editorBarRight?: import('svelte').Snippet enablePreprocessorSnippet?: boolean } @@ -155,7 +155,7 @@ lastDeployedCode = undefined, disableAi = false, assets = $bindable(), - editor_bar_right, + editorBarRight, enablePreprocessorSnippet = false }: Props = $props() @@ -883,7 +883,7 @@ } } - setContext('disableTooltips', customUi?.disableTooltips === true) + setContext('disableTooltips', untrack(() => customUi)?.disableTooltips === true) let codePanelSize = $state(70) let testPanelSize = $state(30) @@ -1042,7 +1042,7 @@ bind:showHistoryDrawer > {#snippet right()} - {@render editor_bar_right?.()} + {@render editorBarRight?.()} {/snippet} {/if} diff --git a/frontend/src/lib/components/ScriptPicker.svelte b/frontend/src/lib/components/ScriptPicker.svelte index 5fa0618edd..803684f49e 100644 --- a/frontend/src/lib/components/ScriptPicker.svelte +++ b/frontend/src/lib/components/ScriptPicker.svelte @@ -52,7 +52,7 @@ let lang: SupportedLanguage | undefined = $state() let options: [[string, any, any, string | undefined]] = [['Script', 'script', Code2, undefined]] - allowFlow && options.push(['Flow', 'flow', FlowIcon, '#14b8a6']) + untrack(() => allowFlow) && options.push(['Flow', 'flow', FlowIcon, '#14b8a6']) const dispatch = createEventDispatcher() async function loadItems(): Promise { diff --git a/frontend/src/lib/components/ScriptWrapper.svelte b/frontend/src/lib/components/ScriptWrapper.svelte index 5e53dc09f3..eec781ce77 100644 --- a/frontend/src/lib/components/ScriptWrapper.svelte +++ b/frontend/src/lib/components/ScriptWrapper.svelte @@ -1,11 +1,12 @@ diff --git a/frontend/src/lib/components/Scrollable.svelte b/frontend/src/lib/components/Scrollable.svelte index 37e3ae2933..7c34b3cbe1 100644 --- a/frontend/src/lib/components/Scrollable.svelte +++ b/frontend/src/lib/components/Scrollable.svelte @@ -2,14 +2,19 @@ import { onMount, onDestroy } from 'svelte' import { twMerge } from 'tailwind-merge' - let isAtBottom: boolean = false - let isScrollable = false + let isAtBottom: boolean = $state(false) + let isScrollable = $state(false) - export let id: string | null | undefined = undefined - export let scrollableClass: string = '' - export let shiftedShadow: boolean = false + interface Props { + id?: string | null | undefined + scrollableClass?: string + shiftedShadow?: boolean + children?: import('svelte').Snippet + } + + let { id = undefined, scrollableClass = '', shiftedShadow = false, children }: Props = $props() let mutationObserver: MutationObserver - let el: HTMLDivElement + let el: HTMLDivElement | undefined = $state() function handleScroll(event) { const scrollableElement = event.target @@ -20,7 +25,8 @@ } function checkIfScrollable(el) { - return el.scrollHeight > el.clientHeight + if (!el) return false + return el?.scrollHeight > el?.clientHeight } function observeScrollability(el) { @@ -33,7 +39,7 @@ } export function scrollIntoView(top: number) { - el.scrollTo({ top, behavior: 'smooth' }) + el?.scrollTo({ top, behavior: 'smooth' }) } onMount(() => { observeScrollability(el) @@ -45,8 +51,8 @@ - - + + {@render children?.()} {#if !isAtBottom && isScrollable} opts)) function filterItems() { let trimmed = filter.trim() diff --git a/frontend/src/lib/components/ServiceLogsInner.svelte b/frontend/src/lib/components/ServiceLogsInner.svelte index 0f4f923cd6..abcffa32ef 100644 --- a/frontend/src/lib/components/ServiceLogsInner.svelte +++ b/frontend/src/lib/components/ServiceLogsInner.svelte @@ -22,7 +22,7 @@ import SplitPanesOrColumnOnMobile from './splitPanes/SplitPanesOrColumnOnMobile.svelte' import Select from './select/Select.svelte' import { goto } from '$lib/navigation' - import { page } from '$app/stores' + import { page } from '$app/state' import { watch } from 'runed' interface Props { @@ -169,13 +169,13 @@ type Selected = { mode: string; workerGroup: string; hostname: string } let initialSelected = - $page.url.searchParams.get('mode') && - $page.url.searchParams.get('workerGroup') && - $page.url.searchParams.get('hostname') + page.url.searchParams.get('mode') && + page.url.searchParams.get('workerGroup') && + page.url.searchParams.get('hostname') ? { - mode: $page.url.searchParams.get('mode')!, - workerGroup: $page.url.searchParams.get('workerGroup')!, - hostname: $page.url.searchParams.get('hostname')! + mode: page.url.searchParams.get('mode')!, + workerGroup: page.url.searchParams.get('workerGroup')!, + hostname: page.url.searchParams.get('hostname')! } : undefined let selected: Selected | undefined = $state(initialSelected) @@ -663,7 +663,7 @@ { + onClick={() => { let logLineNumber = document.line_number[0] let logFile = document.file_name[0] let host = document.host[0] diff --git a/frontend/src/lib/components/ShareModal.svelte b/frontend/src/lib/components/ShareModal.svelte index c8c69106ed..10cf5f09e0 100644 --- a/frontend/src/lib/components/ShareModal.svelte +++ b/frontend/src/lib/components/ShareModal.svelte @@ -159,12 +159,14 @@ {/if} {#if acls?.length > 0} - - - owner - - - + + {#snippet headerRow()} + + owner + + + + {/snippet} {#snippet body()} {#each acls as [owner, write]} diff --git a/frontend/src/lib/components/SimpleEditor.svelte b/frontend/src/lib/components/SimpleEditor.svelte index 2fdd14e3f9..31da7fd802 100644 --- a/frontend/src/lib/components/SimpleEditor.svelte +++ b/frontend/src/lib/components/SimpleEditor.svelte @@ -130,7 +130,7 @@ const dispatch = createEventDispatcher() - const uri = `file:///${hash}.${langToExt(lang)}` + const uri = `file:///${untrack(() => hash)}.${langToExt(untrack(() => lang))}` export function getCode(): string { if (valueAfterDispose != undefined) { diff --git a/frontend/src/lib/components/Slider.svelte b/frontend/src/lib/components/Slider.svelte index c2ca0abbdd..e3269cde09 100644 --- a/frontend/src/lib/components/Slider.svelte +++ b/frontend/src/lib/components/Slider.svelte @@ -5,10 +5,21 @@ import Tooltip from './Tooltip.svelte' import { twMerge } from 'tailwind-merge' - export let text: string - export let tooltip: string | undefined = undefined - export let view = false - export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md' + interface Props { + text: string; + tooltip?: string | undefined; + view?: boolean; + size?: 'xs' | 'sm' | 'md' | 'lg'; + children?: import('svelte').Snippet; + } + + let { + text, + tooltip = undefined, + view = $bindable(false), + size = 'md', + children + }: Props = $props(); {#if view} - + {@render children?.()} {/if} diff --git a/frontend/src/lib/components/StringTypeNarrowing.svelte b/frontend/src/lib/components/StringTypeNarrowing.svelte index bce364d44f..7d84b4c4fc 100644 --- a/frontend/src/lib/components/StringTypeNarrowing.svelte +++ b/frontend/src/lib/components/StringTypeNarrowing.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/Summary.svelte b/frontend/src/lib/components/Summary.svelte index 42d0b48ba5..1b4c3f2c2e 100644 --- a/frontend/src/lib/components/Summary.svelte +++ b/frontend/src/lib/components/Summary.svelte @@ -2,8 +2,12 @@ import { Pen } from 'lucide-svelte' import TextInput from './text_input/TextInput.svelte' - export let value: string - export let disabled = false + interface Props { + value: string; + disabled?: boolean; + } + + let { value = $bindable(), disabled = false }: Props = $props(); function blur(e: KeyboardEvent) { e.key === 'Enter' && (e?.target as any)?.blur() diff --git a/frontend/src/lib/components/SupabaseConnect.svelte b/frontend/src/lib/components/SupabaseConnect.svelte index d16960ffbc..e44399ee84 100644 --- a/frontend/src/lib/components/SupabaseConnect.svelte +++ b/frontend/src/lib/components/SupabaseConnect.svelte @@ -1,4 +1,6 @@ @@ -120,7 +124,7 @@ {#each databases as database} { + onclick={() => { selectedDatabase = database step = 'resource' diff --git a/frontend/src/lib/components/SuperadminSettings.svelte b/frontend/src/lib/components/SuperadminSettings.svelte index f9b446b04e..c6cbe9f421 100644 --- a/frontend/src/lib/components/SuperadminSettings.svelte +++ b/frontend/src/lib/components/SuperadminSettings.svelte @@ -98,15 +98,17 @@ → {uptodateVersion} {/if} - - {#if isCloudHosted()} - The cloud version is updated daily. - {:else} - How to update? - - docker: docker compose up -d - - helm - {/if} - + {#snippet text()} + + {#if isCloudHosted()} + The cloud version is updated daily. + {:else} + How to update? + - docker: docker compose up -d + - helm + {/if} + + {/snippet} {/snippet} {#snippet actions()} diff --git a/frontend/src/lib/components/SuperadminSettingsInner.svelte b/frontend/src/lib/components/SuperadminSettingsInner.svelte index 4d6b0e33f1..1f33e768d8 100644 --- a/frontend/src/lib/components/SuperadminSettingsInner.svelte +++ b/frontend/src/lib/components/SuperadminSettingsInner.svelte @@ -8,7 +8,7 @@ import { sendUserToast } from '$lib/toast' import { base } from '$lib/base' import SearchItems from './SearchItems.svelte' - import { page } from '$app/stores' + import { page } from '$app/state' import { goto as gotoUrl } from '$app/navigation' import Version from './Version.svelte' import Uptodate from './Uptodate.svelte' @@ -50,9 +50,9 @@ } = $props() function removeHash() { - const index = $page.url.href.lastIndexOf('#') + const index = page.url.href.lastIndexOf('#') if (index === -1) return - const hashRemoved = $page.url.href.slice(0, index) + const hashRemoved = page.url.href.slice(0, index) gotoUrl(hashRemoved) } diff --git a/frontend/src/lib/components/TableCustom.svelte b/frontend/src/lib/components/TableCustom.svelte index e40a2c9706..a508d48c8f 100644 --- a/frontend/src/lib/components/TableCustom.svelte +++ b/frontend/src/lib/components/TableCustom.svelte @@ -1,37 +1,53 @@ - + - + {@render headerRow?.()} - + {@render body?.()} {#if paginated} dispatch('next')} + onclick={() => dispatch('next')} > Next dispatch('previous')} + onclick={() => dispatch('previous')} > Previous diff --git a/frontend/src/lib/components/TemplateEditor.svelte b/frontend/src/lib/components/TemplateEditor.svelte index f3ad00ffc3..8046e6ec97 100644 --- a/frontend/src/lib/components/TemplateEditor.svelte +++ b/frontend/src/lib/components/TemplateEditor.svelte @@ -412,7 +412,7 @@ const lang = 'template' const dispatch = createEventDispatcher() - const uri = `file:///${hash}.ts` + const uri = `file:///${untrack(() => hash)}.ts` export function insertAtCursor(code: string): void { if (editor) { diff --git a/frontend/src/lib/components/TestConnection.svelte b/frontend/src/lib/components/TestConnection.svelte index 576bbc9334..7c59a2a324 100644 --- a/frontend/src/lib/components/TestConnection.svelte +++ b/frontend/src/lib/components/TestConnection.svelte @@ -7,10 +7,19 @@ import { workspaceStore } from '$lib/stores' import { tryEvery } from '$lib/utils' - export let workspaceOverride: string | undefined = undefined - export let resourceType: string | undefined - export let args: Record | any = {} - export let buttonTextOverride: string | undefined = undefined + interface Props { + workspaceOverride?: string | undefined; + resourceType: string | undefined; + args?: Record | any; + buttonTextOverride?: string | undefined; + } + + let { + workspaceOverride = undefined, + resourceType, + args = {}, + buttonTextOverride = undefined + }: Props = $props(); const scripts: { [key: string]: { @@ -166,7 +175,7 @@ export async function main(bucket: any) { } } - let loading = false + let loading = $state(false) async function testConnection() { if (!resourceType) return loading = true diff --git a/frontend/src/lib/components/Toast.svelte b/frontend/src/lib/components/Toast.svelte index 13e857ed6f..034887235e 100644 --- a/frontend/src/lib/components/Toast.svelte +++ b/frontend/src/lib/components/Toast.svelte @@ -82,14 +82,14 @@ } }) - let color = classes[type] + let color = classes[untrack(() => type)] let containerClass = { success: 'toast-success', error: 'toast-error', info: 'toast-info', warning: 'toast-warning' - }[type] + }[untrack(() => type)] let Icon = $derived(icons[type]) diff --git a/frontend/src/lib/components/Toggle.svelte b/frontend/src/lib/components/Toggle.svelte index 6b502bcbfa..4ae37d325f 100644 --- a/frontend/src/lib/components/Toggle.svelte +++ b/frontend/src/lib/components/Toggle.svelte @@ -3,7 +3,7 @@ const bubble = createBubbler() import { classNames } from '$lib/utils' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' import { twMerge } from 'tailwind-merge' import Tooltip from './Tooltip.svelte' import { AlertTriangle } from 'lucide-svelte' @@ -54,7 +54,7 @@ }: Props = $props() const dispatch = createEventDispatcher<{ change: boolean }>() - const bothOptions = Boolean(options.left) && Boolean(options.right) + const bothOptions = Boolean(untrack(() => options).left) && Boolean(untrack(() => options).right) import { urlize } from '$lib/utils' - export let text: string - $: parsed = text ? urlize(text, 'html') : '' + interface Props { + text: string; + } + + let { text }: Props = $props(); + let parsed = $derived(text ? urlize(text, 'html') : '') {@html parsed} diff --git a/frontend/src/lib/components/Version.svelte b/frontend/src/lib/components/Version.svelte index 9406bed01f..aa0b58624d 100644 --- a/frontend/src/lib/components/Version.svelte +++ b/frontend/src/lib/components/Version.svelte @@ -1,7 +1,7 @@ {#if flow_status} diff --git a/frontend/src/lib/components/ZitadelSetting.svelte b/frontend/src/lib/components/ZitadelSetting.svelte index ce8b879db9..430c4c588c 100644 --- a/frontend/src/lib/components/ZitadelSetting.svelte +++ b/frontend/src/lib/components/ZitadelSetting.svelte @@ -1,16 +1,20 @@ - + - import { setContext } from 'svelte' + import { setContext, untrack } from 'svelte' import type { Writable } from 'svelte/store' import type { GroupContext } from '../types' @@ -11,7 +11,10 @@ let { context, id, children }: Props = $props() - setContext('GroupContext', { id, context }) + setContext('GroupContext', { + id: untrack(() => id), + context: untrack(() => context) + }) {@render children?.()} diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index 547fff4723..50e815c917 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -72,17 +72,25 @@ const listInputs: ListInputs | undefined = getContext('ListInputs') let resolvedConfig = $state( - initConfig(components['buttoncomponent'].initialData.configuration, configuration) + initConfig( + components['buttoncomponent'].initialData.configuration, + untrack(() => configuration) + ) ) - let outputs = initOutput($worldStore, id, { - result: undefined, - loading: false, - jobId: undefined - }) + let outputs = initOutput( + $worldStore, + untrack(() => id), + { + result: undefined, + loading: false, + jobId: undefined + } + ) - if (controls) { - $componentControl[id] = controls + const untrackedControls = untrack(() => controls) + if (untrackedControls) { + $componentControl[untrack(() => id)] = untrackedControls } let runnableComponent: RunnableComponent | undefined = $state() @@ -203,7 +211,12 @@ let loading = $state(false) let backgroundClickFeedback = $state(false) - let css = $state(initCss($app.css?.buttoncomponent, customCss)) + let css = $state( + initCss( + $app.css?.buttoncomponent, + untrack(() => customCss) + ) + ) $effect(() => { errorHandledByComponent = resolvedConfig?.onError?.selected !== 'errorOverlay' }) diff --git a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte index 68064c0136..e7e606d8f3 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte @@ -1,6 +1,6 @@ {#each Object.keys(components['alertcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppBarChart.svelte b/frontend/src/lib/components/apps/components/display/AppBarChart.svelte index f873e149bb..f8d78cadeb 100644 --- a/frontend/src/lib/components/apps/components/display/AppBarChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppBarChart.svelte @@ -11,7 +11,7 @@ Title, Tooltip } from 'chart.js' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { Bar, Line } from '$lib/components/chartjs-wrappers/chartJs' import { initConfig, initOutput } from '../../editor/appUtils' import type { AppInput } from '../../inputType' @@ -43,10 +43,10 @@ const { app, worldStore } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['barchartcomponent'].initialData.configuration, configuration) + initConfig(components['barchartcomponent'].initialData.configuration, untrack(() => configuration)) ) - let outputs = initOutput($worldStore, id, { + let outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -119,7 +119,7 @@ } }) - let css = $state(initCss($app.css?.barchartcomponent, customCss)) + let css = $state(initCss($app.css?.barchartcomponent, untrack(() => customCss))) {#each Object.keys(components['barchartcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte b/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte index 4b96de346e..f92d42f12a 100644 --- a/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte +++ b/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte @@ -39,12 +39,12 @@ const { app, focusedGrid, selectedComponent, worldStore, connectingInput, componentControl } = getContext('AppViewerContext') - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect.pre(() => { render && !everRender && (everRender = true) }) - let outputs = initOutput($worldStore, id, { + let outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, inputs: {}, @@ -52,7 +52,7 @@ }) const resolvedConfig = $state( - initConfig(components['carousellistcomponent'].initialData.configuration, configuration) + initConfig(components['carousellistcomponent'].initialData.configuration, untrack(() => configuration)) ) function onFocus() { @@ -62,7 +62,7 @@ } } - let css = $state(initCss($app.css?.carousellistcomponent, customCss)) + let css = $state(initCss($app.css?.carousellistcomponent, untrack(() => customCss))) let result: any[] | undefined = $state(undefined) let inputs = $state({}) @@ -105,7 +105,7 @@ currentPageIndex != undefined && untrack(() => handleIndexChange()) }) - $componentControl[id] = { + $componentControl[untrack(() => id)] = { setSelectedIndex: (index: number) => { if (Array.isArray(result) && index >= 0 && index < result.length) { currentPageIndex = index diff --git a/frontend/src/lib/components/apps/components/display/AppChartJs.svelte b/frontend/src/lib/components/apps/components/display/AppChartJs.svelte index 7ac9cdb9b9..58ef1723fa 100644 --- a/frontend/src/lib/components/apps/components/display/AppChartJs.svelte +++ b/frontend/src/lib/components/apps/components/display/AppChartJs.svelte @@ -5,7 +5,7 @@ import type { AppInput } from '../../inputType' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initConfig, initOutput } from '../../editor/appUtils' import { components } from '../../editor/component' import ResolveConfig from '../helpers/ResolveConfig.svelte' @@ -32,7 +32,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -42,7 +42,7 @@ let result: undefined = $state(undefined) const resolvedConfig = $state( - initConfig(components['chartjscomponent'].initialData.configuration, configuration) + initConfig(components['chartjscomponent'].initialData.configuration, untrack(() => configuration)) ) let options = $derived({ responsive: true, @@ -51,7 +51,7 @@ ...(resolvedConfig.options ?? {}) } as ChartOptions) - let css = $state(initCss($app.css?.chartjscomponent, customCss)) + let css = $state(initCss($app.css?.chartjscomponent, untrack(() => customCss))) {#each Object.keys(components['chartjscomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte b/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte index d4b35a97f2..2833b84612 100644 --- a/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte +++ b/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte @@ -10,7 +10,7 @@ RichConfigurations } from '../../types' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initConfig, initOutput } from '../../editor/appUtils' import { components } from '../../editor/component' import ResolveConfig from '../helpers/ResolveConfig.svelte' @@ -51,7 +51,7 @@ const { app, worldStore, darkMode } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -61,7 +61,7 @@ let result: undefined = $state(undefined) const resolvedConfig = $state( - initConfig(components['chartjscomponent'].initialData.configuration, configuration) + initConfig(components['chartjscomponent'].initialData.configuration, untrack(() => configuration)) ) function hasScales() { @@ -110,7 +110,7 @@ : result ) - let css = $state(initCss($app.css?.chartjscomponent, customCss)) + let css = $state(initCss($app.css?.chartjscomponent, untrack(() => customCss))) {#if datasets} diff --git a/frontend/src/lib/components/apps/components/display/AppChat.svelte b/frontend/src/lib/components/apps/components/display/AppChat.svelte index 49e6f5d2a1..15bdc7bc57 100644 --- a/frontend/src/lib/components/apps/components/display/AppChat.svelte +++ b/frontend/src/lib/components/apps/components/display/AppChat.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte b/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte index 5b3fd64173..d2831f76a3 100644 --- a/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte +++ b/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte @@ -38,10 +38,10 @@ const requireHtmlApproval = getContext(IS_APP_PUBLIC_CONTEXT_KEY) let resolvedConfig = $state( - initConfig(components['jobiddisplaycomponent'].initialData.configuration, configuration) + initConfig(components['jobiddisplaycomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, jobId: undefined as string | undefined @@ -49,7 +49,7 @@ initializing = false - let css = $state(initCss($app.css?.jobiddisplaycomponent, customCss)) + let css = $state(initCss($app.css?.jobiddisplaycomponent, untrack(() => customCss))) let jobLoader: JobLoader | undefined = $state(undefined) let testIsLoading: boolean = $state(false) diff --git a/frontend/src/lib/components/apps/components/display/AppDownload.svelte b/frontend/src/lib/components/apps/components/display/AppDownload.svelte index 0f38afe1db..48a8101f1b 100644 --- a/frontend/src/lib/components/apps/components/display/AppDownload.svelte +++ b/frontend/src/lib/components/apps/components/display/AppDownload.svelte @@ -36,14 +36,14 @@ }: Props = $props() const resolvedConfig = $state( - initConfig(components['downloadcomponent'].initialData.configuration, configuration) + initConfig(components['downloadcomponent'].initialData.configuration, untrack(() => configuration)) ) const { app, worldStore, appPath, workspace, isEditor } = getContext('AppViewerContext') //used so that we can count number of outputs setup for first refresh - initOutput($worldStore, id, {}) + initOutput($worldStore, untrack(() => id), {}) let beforeIconComponent: any = $state() let afterIconComponent: any = $state() @@ -106,7 +106,7 @@ } } - let css = $state(initCss($app.css?.downloadcomponent, customCss)) + let css = $state(initCss($app.css?.downloadcomponent, untrack(() => customCss))) $effect(() => { resolvedConfig.beforeIcon && beforeIconComponent && untrack(() => handleBeforeIcon()) }) diff --git a/frontend/src/lib/components/apps/components/display/AppHtml.svelte b/frontend/src/lib/components/apps/components/display/AppHtml.svelte index fa8f49b3a4..3975a54cf5 100644 --- a/frontend/src/lib/components/apps/components/display/AppHtml.svelte +++ b/frontend/src/lib/components/apps/components/display/AppHtml.svelte @@ -1,5 +1,5 @@ {#each Object.keys(css ?? {}) as key (key)} @@ -46,6 +46,7 @@ {/each} {#if render} + { if ($mode !== 'preview') { diff --git a/frontend/src/lib/components/apps/components/display/AppIcon.svelte b/frontend/src/lib/components/apps/components/display/AppIcon.svelte index c4e6862c04..c97f005dc6 100644 --- a/frontend/src/lib/components/apps/components/display/AppIcon.svelte +++ b/frontend/src/lib/components/apps/components/display/AppIcon.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte b/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte index eace729280..d9b4ac4c0a 100644 --- a/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte +++ b/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte @@ -37,10 +37,10 @@ const { app, worldStore, workspace } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['jobidlogcomponent'].initialData.configuration, configuration) + initConfig(components['jobidlogcomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, jobId: undefined @@ -48,7 +48,7 @@ initializing = false - let css = $state(initCss($app.css?.jobidlogcomponent, customCss)) + let css = $state(initCss($app.css?.jobidlogcomponent, untrack(() => customCss))) let jobLoader: JobLoader | undefined = $state(undefined) let testIsLoading: boolean = $state(false) diff --git a/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte b/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte index ecee9c1199..9cf5b59b6e 100644 --- a/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte +++ b/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte @@ -38,10 +38,10 @@ const { app, worldStore, workspace } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['jobprogressbarcomponent'].initialData.configuration, configuration) + initConfig(components['jobprogressbarcomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, jobId: undefined @@ -49,7 +49,7 @@ initializing = false - let css = $state(initCss($app.css?.jobprogressbarcomponent, customCss)) + let css = $state(initCss($app.css?.jobprogressbarcomponent, untrack(() => customCss))) let jobLoader: JobLoader | undefined = $state(undefined) let testIsLoading: boolean = $state(false) diff --git a/frontend/src/lib/components/apps/components/display/AppMap.svelte b/frontend/src/lib/components/apps/components/display/AppMap.svelte index a630226d7b..1f04716110 100644 --- a/frontend/src/lib/components/apps/components/display/AppMap.svelte +++ b/frontend/src/lib/components/apps/components/display/AppMap.svelte @@ -1,7 +1,7 @@ {#each Object.keys(components['navbarcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppPdf.svelte b/frontend/src/lib/components/apps/components/display/AppPdf.svelte index e31cb4ae65..b5d498ca37 100644 --- a/frontend/src/lib/components/apps/components/display/AppPdf.svelte +++ b/frontend/src/lib/components/apps/components/display/AppPdf.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/display/AppPieChart.svelte b/frontend/src/lib/components/apps/components/display/AppPieChart.svelte index d7fde24dc9..ca5671b342 100644 --- a/frontend/src/lib/components/apps/components/display/AppPieChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppPieChart.svelte @@ -16,7 +16,7 @@ import InputValue from '../helpers/InputValue.svelte' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initOutput } from '../../editor/appUtils' import { twMerge } from 'tailwind-merge' import ResolveStyle from '../helpers/ResolveStyle.svelte' @@ -41,7 +41,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -87,7 +87,7 @@ ] }) - let css = $state(initCss($app.css?.piechartcomponent, customCss)) + let css = $state(initCss($app.css?.piechartcomponent, untrack(() => customCss))) {#each Object.keys(css ?? {}) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte b/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte index 5cdccb672d..c0308458ad 100644 --- a/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte +++ b/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte @@ -36,16 +36,16 @@ getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['recomputeallcomponent'].initialData.configuration, configuration) + initConfig(components['recomputeallcomponent'].initialData.configuration, untrack(() => configuration)) ) - initOutput($worldStore, id, { + initOutput($worldStore, untrack(() => id), { loading: undefined }) initializing = false - let css = $state(initCss($app.css?.recomputeallcomponent, customCss)) + let css = $state(initCss($app.css?.recomputeallcomponent, untrack(() => customCss))) function handleRefreshInterval() { if (resolvedConfig.defaultRefreshInterval !== undefined) { diff --git a/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte b/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte index dd0d03e70a..ae139ea7c5 100644 --- a/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte @@ -17,7 +17,7 @@ import InputValue from '../helpers/InputValue.svelte' import type { ChartOptions, ChartData } from 'chart.js' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' import { initOutput } from '../../editor/appUtils' import { twMerge } from 'tailwind-merge' @@ -47,7 +47,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -91,7 +91,7 @@ datasets: result ?? [] } as ChartData<'scatter', (number | Point)[], unknown>) - let css = $state(initCss($app.css?.scatterchartcomponent, customCss)) + let css = $state(initCss($app.css?.scatterchartcomponent, untrack(() => customCss))) {#each Object.keys(css ?? {}) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppStatCard.svelte b/frontend/src/lib/components/apps/components/display/AppStatCard.svelte index f773e75db0..fb6d665408 100644 --- a/frontend/src/lib/components/apps/components/display/AppStatCard.svelte +++ b/frontend/src/lib/components/apps/components/display/AppStatCard.svelte @@ -27,12 +27,12 @@ const { app, worldStore } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['statcomponent'].initialData.configuration, configuration) + initConfig(components['statcomponent'].initialData.configuration, untrack(() => configuration)) ) - initOutput($worldStore, id, {}) + initOutput($worldStore, untrack(() => id), {}) - let css = $state(initCss($app.css?.statcomponent, customCss)) + let css = $state(initCss($app.css?.statcomponent, untrack(() => customCss))) let iconComponent: any = $state() diff --git a/frontend/src/lib/components/apps/components/display/AppText.svelte b/frontend/src/lib/components/apps/components/display/AppText.svelte index a7f98089f8..03aae9be37 100644 --- a/frontend/src/lib/components/apps/components/display/AppText.svelte +++ b/frontend/src/lib/components/apps/components/display/AppText.svelte @@ -43,7 +43,10 @@ }: Props = $props() let resolvedConfig = $state( - initConfig(components['textcomponent'].initialData.configuration, configuration) + initConfig( + components['textcomponent'].initialData.configuration, + untrack(() => configuration) + ) ) function onEditorMode() { @@ -53,29 +56,40 @@ const { app, worldStore, mode, componentControl } = getContext('AppViewerContext') - let css = $state(initCss($app.css?.textcomponent, customCss)) + let css = $state( + initCss( + $app.css?.textcomponent, + untrack(() => customCss) + ) + ) let result: string | undefined = $state(undefined) + const untrackedComponentInput = untrack(() => componentInput) if ( - componentInput?.type == 'template' || - (componentInput?.type == 'templatev2' && !isCodeInjection(componentInput.eval)) + untrackedComponentInput?.type == 'template' || + (untrackedComponentInput?.type == 'templatev2' && + !isCodeInjection(untrackedComponentInput.eval)) ) { - result = componentInput.eval + result = untrackedComponentInput.eval initializing = false } - $componentControl[id] = { - ...$componentControl[id], + $componentControl[untrack(() => id)] = { + ...$componentControl[untrack(() => id)], setValue(value: string) { result = value } } - const outputs = initOutput($worldStore, id, { - result: untrack(() => result), - loading: initializing - }) + const outputs = initOutput( + $worldStore, + untrack(() => id), + { + result: untrack(() => result), + loading: initializing + } + ) function getComponent() { switch (resolvedConfig.style) { diff --git a/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte b/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte index 638d68d71e..85582683df 100644 --- a/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte +++ b/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte @@ -21,7 +21,7 @@ import InputValue from '../helpers/InputValue.svelte' import type { ChartOptions, ChartData } from 'chart.js' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initCss } from '../../utils' import { initOutput } from '../../editor/appUtils' import { twMerge } from 'tailwind-merge' @@ -47,7 +47,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -105,7 +105,7 @@ datasets: result ?? [] } as ChartData<'scatter', (number | Point)[], unknown>) - let css = $state(initCss($app.css?.timeseriescomponent, customCss)) + let css = $state(initCss($app.css?.timeseriescomponent, untrack(() => customCss))) {#each Object.keys(css ?? {}) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte b/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte index 3f7de3b5ab..95aeef0c32 100644 --- a/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte +++ b/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte @@ -25,7 +25,7 @@ { + onkeydown={(e) => { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { onConfirm() } diff --git a/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte b/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte index 82cd9f805f..13ad56d850 100644 --- a/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte +++ b/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte @@ -30,10 +30,10 @@ const { worldStore, darkMode } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['plotlycomponent'].initialData.configuration, configuration) + initConfig(components['plotlycomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -125,6 +125,7 @@ {/if} + diff --git a/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte b/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte index f6ed334205..87f47af837 100644 --- a/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte +++ b/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte @@ -34,10 +34,10 @@ const { worldStore, darkMode } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['plotlycomponentv2'].initialData.configuration, configuration) + initConfig(components['plotlycomponentv2'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -207,6 +207,7 @@ {/if} + diff --git a/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte b/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte index e5307b4d15..0ab7b2795c 100644 --- a/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte +++ b/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte @@ -1,4 +1,5 @@ {#each Object.keys(components['checkboxcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte b/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte index 9566f39866..62eedc3fc6 100644 --- a/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte +++ b/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte b/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte index d42fdc3ba5..62b785c486 100644 --- a/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte @@ -51,7 +51,7 @@ untrack(() => (counter += 1)) }) - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect.pre(() => { render && !everRender && (everRender = true) }) @@ -66,11 +66,11 @@ debuggingComponents } = getContext('AppViewerContext') - let css = $state(initCss($app.css?.conditionalwrapper, customCss)) + let css = $state(initCss($app.css?.conditionalwrapper, untrack(() => customCss))) let selectedConditionIndex = 0 - let currentNodeId = $state(getFirstNode(nodes)?.id ?? '') + let currentNodeId = $state(getFirstNode(untrack(() => nodes))?.id ?? '') - let outputs = initOutput($worldStore, id, { + let outputs = initOutput($worldStore, untrack(() => id), { currentNodeId: untrack(() => currentNodeId), currentNodeIndex: selectedConditionIndex }) @@ -154,7 +154,7 @@ } } - $componentControl[id] = { + $componentControl[untrack(() => id)] = { setTab: (conditionIndex: number) => { if (conditionIndex !== -1) { onFocus(conditionIndex) diff --git a/frontend/src/lib/components/apps/components/layout/AppDivider.svelte b/frontend/src/lib/components/apps/components/layout/AppDivider.svelte index 97a698dd60..af68c3ad55 100644 --- a/frontend/src/lib/components/apps/components/layout/AppDivider.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppDivider.svelte @@ -1,5 +1,5 @@ {#each Object.keys(components['drawercomponent'].initialData.configuration) as key (key)} @@ -162,6 +162,7 @@ }} fullScreen={$mode !== 'dnd'} > + - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initConfig, initOutput } from '../../editor/appUtils' import SubGridEditor from '../../editor/SubGridEditor.svelte' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' @@ -37,12 +37,12 @@ getContext('AppViewerContext') let page = $state(0) - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect.pre(() => { render && !everRender && (everRender = true) }) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, inputs: {}, @@ -50,7 +50,7 @@ }) let resolvedConfig = $state( - initConfig(components['listcomponent'].initialData.configuration, configuration) + initConfig(components['listcomponent'].initialData.configuration, untrack(() => configuration)) ) function onFocus() { @@ -60,7 +60,7 @@ } } - let css = $state(initCss($app.css?.listcomponent, customCss)) + let css = $state(initCss($app.css?.listcomponent, untrack(() => customCss))) let result: any[] | undefined = $state(undefined) let isCard = $derived(resolvedConfig.width?.selected == 'card') diff --git a/frontend/src/lib/components/apps/components/layout/AppModal.svelte b/frontend/src/lib/components/apps/components/layout/AppModal.svelte index 6232b667fd..9508303630 100644 --- a/frontend/src/lib/components/apps/components/layout/AppModal.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppModal.svelte @@ -1,7 +1,7 @@ diff --git a/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte b/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte index 7572c8c0fe..5a955a8ce6 100644 --- a/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte @@ -10,12 +10,12 @@ import { createEventDispatcher } from 'svelte' import { Globe, Loader2, Save } from 'lucide-svelte' - let jsonViewerDrawer: Drawer + let jsonViewerDrawer: Drawer | undefined = $state() - let code: string = '' + let code: string = $state('') let path: string = '' - let useDraft: boolean = false - let loading = true + let useDraft: boolean = $state(false) + let loading = $state(true) const dispatch = createEventDispatcher() let app: any | undefined = undefined @@ -73,7 +73,7 @@ - jsonViewerDrawer.toggleDrawer()}> + jsonViewerDrawer?.toggleDrawer()}> {#if useDraft} +Draft diff --git a/frontend/src/lib/components/apps/editor/AppPreview.svelte b/frontend/src/lib/components/apps/editor/AppPreview.svelte index 02114e1210..67c7ef4313 100644 --- a/frontend/src/lib/components/apps/editor/AppPreview.svelte +++ b/frontend/src/lib/components/apps/editor/AppPreview.svelte @@ -59,9 +59,9 @@ gotoFn = (path: string, opt?: Record) => window.history.pushState(null, '', path) }: Props = $props() - migrateApp(app) + migrateApp(untrack(() => app)) - const appStore = writable(app) + const appStore = writable(untrack(() => app)) const selectedComponent = writable(undefined) const mode = writable('preview') @@ -74,11 +74,11 @@ const allIdsInPath = writable([]) let ncontext: any = { - ...context, - workspace, + ...untrack(() => context), + workspace: untrack(() => workspace), mode: 'viewer', - summary: summary, - author: policy.on_behalf_of_email + summary: untrack(() => summary), + author: untrack(() => policy).on_behalf_of_email } function resizeWindow() { @@ -90,7 +90,7 @@ const parentWidth = writable(0) let previousDarkMode = document.documentElement.classList.contains('dark') - const darkMode: Writable = writable(app?.darkMode ?? previousDarkMode) + const darkMode: Writable = writable(untrack(() => app)?.darkMode ?? previousDarkMode) onDestroy(() => { setTheme(previousDarkMode) @@ -132,7 +132,7 @@ }) } - let writablePath = writable(appPath) + let writablePath = writable(untrack(() => appPath)) function onPathChange() { writablePath.set(appPath) @@ -146,21 +146,21 @@ runnableInitialized: {} }), app: appStore, - summary: writable(summary), + summary: writable(untrack(() => summary)), selectedComponent, bgRuns: writable([]), mode, connectingInput, - breakpoint, + breakpoint: untrack(() => breakpoint), runnableComponents: writable({}), appPath: writablePath, - workspace, + workspace: untrack(() => workspace), onchange: undefined, - isEditor, + isEditor: untrack(() => isEditor), jobs: parentContext?.jobs ?? writable([]), jobsById: parentContext?.jobsById ?? writable({}), staticExporter: writable({}), - noBackend, + noBackend: untrack(() => noBackend), errorByComponent: writable({}), openDebugRun: writable(undefined), focusedGrid: writable(undefined), @@ -174,9 +174,9 @@ cssEditorOpen: writable(false), previewTheme: writable(undefined), debuggingComponents: writable({}), - replaceStateFn, - gotoFn, - policy, + replaceStateFn: untrack(() => replaceStateFn), + gotoFn: untrack(() => gotoFn), + policy: untrack(() => policy), recomputeAllContext: writable({ loading: false, componentNumber: 0, @@ -319,6 +319,7 @@ {#snippet children({ dataItem })} + ($selectedComponent = [dataItem.id])} diff --git a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte index e717205670..28d8e5912a 100644 --- a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte +++ b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte @@ -297,7 +297,7 @@ 'text-red-500 px-1 text-2xs py-0.5 font-bold w-fit absolute border border-red-500 -bottom-1 shadow left-1/2 transform -translate-x-1/2 z-50 cursor-pointer' )} > - + {#snippet trigger()} {/snippet} diff --git a/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte b/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte index bf70dafd61..c5452be83e 100644 --- a/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte +++ b/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte @@ -4,7 +4,7 @@ const bubble = createBubbler() import Dropdown from '$lib/components/DropdownV2.svelte' import { classNames } from '$lib/utils' - import { createEventDispatcher, getContext } from 'svelte' + import { createEventDispatcher, getContext, untrack } from 'svelte' import type { AppViewerContext } from '../types' import type { DecisionTreeNode } from './component' import { isDebugging } from './settingsPanel/decisionTree/utils' @@ -27,7 +27,7 @@ getContext('AppViewerContext') const dispatch = createEventDispatcher() - let currentNodeId: string = $state($worldStore.outputsById[id]?.currentNodeId?.peak() ?? 'a') + let currentNodeId: string = $state($worldStore.outputsById[untrack(() => id)]?.currentNodeId?.peak() ?? 'a') function subscribeToCurrentNode(id: string) { return $worldStore.outputsById[id]?.currentNodeId?.subscribe( @@ -41,7 +41,7 @@ ) } - let subscription = subscribeToCurrentNode(id) + let subscription = subscribeToCurrentNode(untrack(() => id)) function onDebugNode(debuggedNodeIndex: number | undefined) { if (debuggedNodeIndex === undefined) { @@ -63,7 +63,7 @@ }) let renderCount: number = $state(0) - let lastNodes: DecisionTreeNode[] = nodes + let lastNodes: DecisionTreeNode[] = untrack(() => nodes) function onNodesChange(newNodes: DecisionTreeNode[]) { if (JSON.stringify(newNodes) !== JSON.stringify(lastNodes)) { diff --git a/frontend/src/lib/components/apps/editor/GridEditor.svelte b/frontend/src/lib/components/apps/editor/GridEditor.svelte index d412bc1c56..d787564c0c 100644 --- a/frontend/src/lib/components/apps/editor/GridEditor.svelte +++ b/frontend/src/lib/components/apps/editor/GridEditor.svelte @@ -184,6 +184,7 @@ + rowHeight) let containerHeight = $derived(getContainerHeight(items, yPerPx, getComputedCols)) @@ -71,7 +71,7 @@ yPerPx, width: containerWidth }) - }, throttleUpdate) + }, untrack(() => throttleUpdate)) onMount(() => { setTimeout(() => { diff --git a/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte b/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte index 687262cf36..e00a128bf4 100644 --- a/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte +++ b/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte @@ -1,4 +1,6 @@ (isActive = x)) - let everVisible = $state(visible) + let everVisible = $state(untrack(() => visible)) $effect.pre(() => { visible && !everVisible && (everVisible = true) @@ -199,6 +199,7 @@ {#if everVisible || $app.eagerRendering} + - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import ComponentInner from './ComponentInner.svelte' import ComponentRendered from './ComponentRendered.svelte' import type { AppComponent } from './components' @@ -25,7 +25,7 @@ overlapped = undefined, componentDraggedId = undefined }: Props = $props() - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect(() => { render && !everRender && (everRender = true) diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte index c50b0ad656..2971a52654 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte @@ -76,7 +76,7 @@ entries.sort((a, b) => (b.order ?? 0) - (a.order ?? 0) + a.name.localeCompare(b.name)) - let search = '' + let search = $state('') @@ -98,12 +98,15 @@ } }} > - - - - {name} - - + {#snippet titleSlot()} + {@const SvelteComponent = icon} + + + + {name} + + + {/snippet} {#if description} {description} {/if} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte index 7460c30de9..3f65904c77 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte @@ -15,9 +15,9 @@ let customcomponents: Array<{ name: string path: string - }> = [] + }> = $state([]) - let loading: boolean = false + let loading: boolean = $state(false) async function getCustomComponents() { loading = true @@ -44,7 +44,7 @@ } }, name: nameField, - js: await files[0].text() + js: await files?.[0]?.text?.() } } }) @@ -61,10 +61,10 @@ nameField = '' } - let nameField: string = '' - let reactVersion: string = '18.2.0' - let files: FileList - let useReact = true + let nameField: string = $state('') + let reactVersion: string = $state('18.2.0') + let files: FileList | undefined = $state() + let useReact = $state(true) getCustomComponents() diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte index 6263bc8026..f4d8c40f72 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte @@ -2,7 +2,7 @@ import Button from '$lib/components/common/button/Button.svelte' import Popover from '$lib/components/meltComponents/Popover.svelte' import { Pen } from 'lucide-svelte' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' interface Props { kind: string @@ -14,7 +14,7 @@ let { kind, row }: Props = $props() - let editedName = $state(row.name) + let editedName = $state(untrack(() => row).name) const dispatch = createEventDispatcher() function onkeydown(e) { diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte index cf5bda33c7..676c59c12d 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte @@ -30,7 +30,7 @@ componentProperty = undefined }: Props = $props() const { app } = getContext('AppViewerContext') - const styleStore = createStyleStore(properties) + const styleStore = createStyleStore(untrack(() => properties)) setContext(STYLE_STORE_KEY, styleStore) let multiValues: Record = $state(initiateMultiValues()) @@ -210,12 +210,11 @@ toggleClasses=" !rounded-b-none !py-0 {isOpen[prefix] ? '!bg-surface-secondary hover:!bg-surface-hover' : ''}" > - - + {#snippet titleSlot()} {group} - + {/snippet} {#each property[group] as p} {@const { diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte index b4efdb87d4..54d9da3a33 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte b/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte index 579b769801..3c1a63ad81 100644 --- a/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte +++ b/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte @@ -1,6 +1,6 @@ diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte index 9b9d1f3563..992c52de83 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte index 6fb7b7be9b..be54285d84 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte @@ -1,7 +1,7 @@ - - - - - + {#snippet selectedTitle()} + + + + + {/snippet} {/if} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte index af6f20e510..23419e51be 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte @@ -6,7 +6,7 @@ import type { InlineScript, Runnable, StaticAppInput } from '$lib/components/apps/inputType' import WorkspaceScriptList from './WorkspaceScriptList.svelte' import WorkspaceFlowList from './WorkspaceFlowList.svelte' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' import type { Schema } from '$lib/common' import { schemaToInputsSpec } from '$lib/components/apps/utils' import { defaultIfEmptyString, emptySchema } from '$lib/utils' @@ -34,7 +34,7 @@ // const { app, workspace } = getContext('AppViewerContext') let tab: TabType = $state( - onlyFlow + untrack(() => onlyFlow) ? 'workspaceflows' : unusedInlineScripts?.length > 0 ? 'inlinescripts' diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte index 877c48bf35..915e66e4db 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/apps/svelte-grid/Grid.svelte b/frontend/src/lib/components/apps/svelte-grid/Grid.svelte index 4ffb2414ee..fd61edce4f 100644 --- a/frontend/src/lib/components/apps/svelte-grid/Grid.svelte +++ b/frontend/src/lib/components/apps/svelte-grid/Grid.svelte @@ -16,7 +16,7 @@ import { getContainerHeight } from './utils/container' import { moveItem, getItemById, specifyUndefinedColumns } from './utils/item' - import { onMount, getContext } from 'svelte' + import { onMount, getContext, untrack } from 'svelte' import { getColumn, throttle } from './utils/other' import MoveResize from './MoveResize.svelte' import type { FilledItem } from './types' @@ -97,7 +97,7 @@ let container = $state() let xPerPx = $state(0) - let yPerPx = rowHeight + let yPerPx = untrack(() => rowHeight) const onResizeThrottled = throttle(() => { if (!getComputedCols) return @@ -108,7 +108,7 @@ yPerPx, width: containerWidth }) - }, throttleUpdate) + }, untrack(() => throttleUpdate)) let mounted = $state(false) @@ -261,7 +261,7 @@ } } - const throttleMatrix = throttle(updateMatrix, throttleResize) + const throttleMatrix = throttle(updateMatrix, untrack(() => throttleResize)) //let hiddenComponents = writable({}) diff --git a/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte b/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte index 033a1a016c..d138023eed 100644 --- a/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte +++ b/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte @@ -1,5 +1,5 @@ @@ -41,29 +42,33 @@ {/if} {#if (asset.kind === 'resource' && resourceDataCacheValue === undefined) || ducklakeNotFound || datatableNotFound} - - - - - Not found - {#if ducklakeNotFound} - - Go to Ducklake settings - - {:else if datatableNotFound} - - Go to Data Table settings - - {:else if asset.kind === 'resource' && resourceDataCacheValue === undefined} - Go to Resources - {/if} - + {#snippet trigger()} + + + + {/snippet} + {#snippet content()} + + Not found + {#if ducklakeNotFound} + + Go to Ducklake settings + + {:else if datatableNotFound} + + Go to Data Table settings + + {:else if asset.kind === 'resource' && resourceDataCacheValue === undefined} + Go to Resources + {/if} + + {/snippet} {:else if assetCanBeExplored(asset, { resource_type: resourceDataCacheValue })} {@render badge()} - - {accessType2} access to column "{columnName}" - + {#snippet text()} + + {accessType2} access to column "{columnName}" + + {/snippet} {/if} {/each} diff --git a/frontend/src/lib/components/assets/AssetsDropdownButton.svelte b/frontend/src/lib/components/assets/AssetsDropdownButton.svelte index 5c530cf606..351ee68331 100644 --- a/frontend/src/lib/components/assets/AssetsDropdownButton.svelte +++ b/frontend/src/lib/components/assets/AssetsDropdownButton.svelte @@ -102,7 +102,7 @@ bind:isOpen escapeBehavior="ignore" > - + {#snippet trigger()} - - + {/snippet} + {#snippet content()} {#each assets as asset} {@const ducklakeNotFound = @@ -144,7 +144,7 @@ contentClasses="py-2 px-4 flex flex-col gap-2" disablePopup={!!asset.access_type} > - + {#snippet trigger()} {formatAssetAccessType(getAccessType(asset)) ?? '?'} - - + {/snippet} + {#snippet content()} {#if !asset.access_type} Could not infer automatically @@ -180,14 +180,14 @@ {/if} - + {/snippet} {asset.path} - + {#snippet text()} {asset.path} - + {/snippet} {liSubtitle?.(asset) ?? @@ -216,7 +216,7 @@ {/each} - + {/snippet} diff --git a/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte b/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte index 177032341b..16effb700a 100644 --- a/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte +++ b/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte @@ -71,11 +71,13 @@ {text} - - {#if tooltip} - {tooltip} - {/if} - + {#snippet text()} + + {#if tooltip} + {tooltip} + {/if} + + {/snippet} {/if} {/snippet} diff --git a/frontend/src/lib/components/assets/VolumesDrawer.svelte b/frontend/src/lib/components/assets/VolumesDrawer.svelte index bd00dd0dba..06d4f9529a 100644 --- a/frontend/src/lib/components/assets/VolumesDrawer.svelte +++ b/frontend/src/lib/components/assets/VolumesDrawer.svelte @@ -52,10 +52,7 @@ refreshKey++ } - function canReadVolume( - createdBy: string, - extraPerms?: { [key: string]: unknown } - ): boolean { + function canReadVolume(createdBy: string, extraPerms?: { [key: string]: unknown }): boolean { if ($userStore?.is_admin) return true const username = $userStore?.username if (username === createdBy || `u/${username}` === createdBy) return true @@ -67,10 +64,7 @@ return pgroups.some((g) => g in perms) } - function canWriteVolume( - createdBy: string, - extraPerms?: { [key: string]: unknown } - ): boolean { + function canWriteVolume(createdBy: string, extraPerms?: { [key: string]: unknown }): boolean { if ($userStore?.is_admin) return true const username = $userStore?.username if (username === createdBy || `u/${username}` === createdBy) return true @@ -83,10 +77,7 @@ (open = false)}> (open = false)}> {#snippet actions()} - + {#snippet trigger()} New volume - Volumes are limited to 20 per workspace and 50 MB per file. Upgrade to Enterprise - Edition to remove these limits. + Volumes are limited to 20 per workspace and 50 MB per file. Upgrade to Enterprise Edition + to remove these limits. {/if} @@ -133,7 +124,8 @@ {:else if !volumes.current?.length} - No volumes yet. Create one above or they are auto-created when a job declares a volume annotation. + No volumes yet. Create one above or they are auto-created when a job declares a volume + annotation. {:else} @@ -151,7 +143,8 @@ /> - {vol.file_count} {vol.file_count === 1 ? 'file' : 'files'} + {vol.file_count} + {vol.file_count === 1 ? 'file' : 'files'} · {displaySize(vol.size_bytes) ?? '0 B'} · owner: {vol.created_by.replace(/^u\//, '')} @@ -167,8 +160,7 @@ iconOnly unifiedSize="sm" endIcon={{ icon: Shield }} - on:click={() => - shareModal?.openDrawer(vol.name, 'volume', true)} + on:click={() => shareModal?.openDrawer(vol.name, 'volume', true)} /> {/if} {#if onExplore && readable} diff --git a/frontend/src/lib/components/chartjs-wrappers/Chart.svelte b/frontend/src/lib/components/chartjs-wrappers/Chart.svelte index 9fdacd47de..66739a7859 100644 --- a/frontend/src/lib/components/chartjs-wrappers/Chart.svelte +++ b/frontend/src/lib/components/chartjs-wrappers/Chart.svelte @@ -27,8 +27,8 @@ untrack(() => { chart = new Chart(canvasElem, { type, - data, - options + data: $state.snapshot(data) as typeof data, + options: $state.snapshot(options) as typeof options }) }) return () => { @@ -37,10 +37,10 @@ }) $effect(() => { - chart + data untrack(() => { if (chart) { - chart.data = data + chart.data = $state.snapshot(data) as typeof data chart.update() } }) diff --git a/frontend/src/lib/components/common/FileProgressBar.svelte b/frontend/src/lib/components/common/FileProgressBar.svelte index d339d9477f..5cb864981b 100644 --- a/frontend/src/lib/components/common/FileProgressBar.svelte +++ b/frontend/src/lib/components/common/FileProgressBar.svelte @@ -1,23 +1,38 @@ {#key color} {#if ended} - + {@render children?.()} {:else} - export let notificationCount = 0 - export let notificationLimit: number | undefined = undefined + interface Props { + notificationCount?: number; + notificationLimit?: number | undefined; + } + + let { notificationCount = 0, notificationLimit = undefined }: Props = $props(); {#if notificationCount > 0} diff --git a/frontend/src/lib/components/common/button/AnimatedButton.svelte b/frontend/src/lib/components/common/button/AnimatedButton.svelte index 7248b891dc..3ceb0ebd4c 100644 --- a/frontend/src/lib/components/common/button/AnimatedButton.svelte +++ b/frontend/src/lib/components/common/button/AnimatedButton.svelte @@ -1,12 +1,26 @@ {#if animate} @@ -19,10 +33,10 @@ {ringColor} {darkMode} > - + {@render children?.()} {:else} - + {@render children?.()} {/if} diff --git a/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte b/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte index 7396b5314b..9ba46928a0 100644 --- a/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte +++ b/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte @@ -1,27 +1,41 @@ @@ -33,7 +47,7 @@ bind:clientWidth bind:clientHeight > - + {@render children?.()}
{@html html} diff --git a/frontend/src/lib/components/LogViewer.svelte b/frontend/src/lib/components/LogViewer.svelte index 0118c32cb8..a62827bba2 100644 --- a/frontend/src/lib/components/LogViewer.svelte +++ b/frontend/src/lib/components/LogViewer.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/MemoryFootprintViewer.svelte b/frontend/src/lib/components/MemoryFootprintViewer.svelte index 66da99e6e6..9547861bc3 100644 --- a/frontend/src/lib/components/MemoryFootprintViewer.svelte +++ b/frontend/src/lib/components/MemoryFootprintViewer.svelte @@ -1,4 +1,6 @@ diff --git a/frontend/src/lib/components/ModuleStatus.svelte b/frontend/src/lib/components/ModuleStatus.svelte index 36f7b54753..351b3e0d03 100644 --- a/frontend/src/lib/components/ModuleStatus.svelte +++ b/frontend/src/lib/components/ModuleStatus.svelte @@ -5,9 +5,13 @@ import { displayDate } from '$lib/utils' import { Hourglass } from 'lucide-svelte' - export let type: FlowStatusModule['type'] - export let scheduled_for: Date | undefined - export let skipped: boolean = false + interface Props { + type: FlowStatusModule['type']; + scheduled_for: Date | undefined; + skipped?: boolean; + } + + let { type, scheduled_for, skipped = false }: Props = $props(); {#if type == 'WaitingForEvents'} diff --git a/frontend/src/lib/components/ModuleTest.svelte b/frontend/src/lib/components/ModuleTest.svelte index 59c8f973ea..37cb96bea7 100644 --- a/frontend/src/lib/components/ModuleTest.svelte +++ b/frontend/src/lib/components/ModuleTest.svelte @@ -8,7 +8,7 @@ } from '$lib/gen' import { workspaceStore } from '$lib/stores' import { getScriptByPath } from '$lib/scripts' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import type { FlowEditorContext } from './flows/types' import JobLoader, { type Callbacks } from './JobLoader.svelte' import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte' @@ -167,8 +167,8 @@ testJob = modulesTestStates.states?.[mod.id]?.testJob }) - modulesTestStates.states[mod.id] = { - ...(modulesTestStates.states?.[mod.id] ?? { loading: false }), + modulesTestStates.states[untrack(() => mod).id] = { + ...(modulesTestStates.states?.[untrack(() => mod).id] ?? { loading: false }), loading: testIsLoading, testJob: testJob } diff --git a/frontend/src/lib/components/OauthExtraParams.svelte b/frontend/src/lib/components/OauthExtraParams.svelte index 826f0237af..eec9cd47b8 100644 --- a/frontend/src/lib/components/OauthExtraParams.svelte +++ b/frontend/src/lib/components/OauthExtraParams.svelte @@ -2,9 +2,13 @@ import { Button } from './common' import { X, Plus } from 'lucide-svelte' - export let extra_params: Record = {} + interface Props { + extra_params?: Record; + } - let extra_params_vec: [string, string][] = Object.entries(extra_params) + let { extra_params = $bindable({}) }: Props = $props(); + + let extra_params_vec: [string, string][] = $state(Object.entries(extra_params)) function sync() { extra_params = Object.fromEntries(extra_params_vec) @@ -13,8 +17,8 @@ {#each extra_params_vec as o} - - + + {#if scopes && Array.isArray(scopes)} - {#each scopes as v} + {#each scopes as v, i} - + e.detail && loadUsers()}> - - - - {#if selectedDisplayName} - {selectedDisplayName} + {#snippet trigger()} + + + + {#if selectedDisplayName} + {selectedDisplayName} + {/if} + + + {/snippet} + {#snippet content({ close: closePopover })} + + {label} + + {#if targetEmail} + onSelect('target')} + > + + {targetUsername} + {isDeployment ? '(target)' : '(current)'} + {/if} - - - - {label} - - {#if targetEmail} + + onSelect('me')} + > + + {$userStore?.username} + (me) + + onSelect('target')} + onclick={() => { + closePopover() + openModal() + }} > - - {targetUsername} - {isDeployment ? '(target)' : '(current)'} + {#if selected === 'custom' && customUsername} + + {customUsername} + (custom) + {:else} + + + Pick from workspace… + {/if} - {/if} - - onSelect('me')} - > - - {$userStore?.username} - (me) - - - { - closePopover() - openModal() - }} - > - {#if selected === 'custom' && customUsername} - - {customUsername} - (custom) - {:else} - - - Pick from workspace… - {/if} - - + + {/snippet} diff --git a/frontend/src/lib/components/PageHeader.svelte b/frontend/src/lib/components/PageHeader.svelte index 07b02227d4..556ac1b0cc 100644 --- a/frontend/src/lib/components/PageHeader.svelte +++ b/frontend/src/lib/components/PageHeader.svelte @@ -1,11 +1,23 @@ @@ -31,9 +43,9 @@ {/if} - {#if $$slots.default} + {#if children} - + {@render children?.()} {/if} diff --git a/frontend/src/lib/components/ParqetCsvTableRenderer.svelte b/frontend/src/lib/components/ParqetCsvTableRenderer.svelte index 07a8c267a9..262be32363 100644 --- a/frontend/src/lib/components/ParqetCsvTableRenderer.svelte +++ b/frontend/src/lib/components/ParqetCsvTableRenderer.svelte @@ -1,4 +1,6 @@ @@ -182,7 +189,7 @@ Separator - mountGrid()}> + mountGrid()}> , ; \t diff --git a/frontend/src/lib/components/PermissionHistory.svelte b/frontend/src/lib/components/PermissionHistory.svelte index 82d646bd53..23f3ec151f 100644 --- a/frontend/src/lib/components/PermissionHistory.svelte +++ b/frontend/src/lib/components/PermissionHistory.svelte @@ -79,12 +79,14 @@ No permission changes recorded yet {:else} - - Changed By - Change Type - Affected - Date - + {#snippet headerRow()} + + Changed By + Change Type + Affected + Date + + {/snippet} {#snippet body()} {#each history as change} diff --git a/frontend/src/lib/components/PersistentScriptDrawer.svelte b/frontend/src/lib/components/PersistentScriptDrawer.svelte index aa5c869f31..23fa122b7d 100644 --- a/frontend/src/lib/components/PersistentScriptDrawer.svelte +++ b/frontend/src/lib/components/PersistentScriptDrawer.svelte @@ -10,19 +10,19 @@ import { Hourglass, Loader2, Play, RefreshCw } from 'lucide-svelte' let dispatch = createEventDispatcher() - let drawer: Drawer + let drawer: Drawer | undefined = $state() - let script: Script - let loadQueuedJobs = true - let queuedJobsLoading = false + let script: Script | undefined = $state() + let loadQueuedJobs = $state(true) + let queuedJobsLoading = $state(false) let queuedJobs: { status: 'running' | 'queued' jobId: string scheduledFor: string scriptHash: string - }[] = [] + }[] = $state([]) - let cancellingInProgress = false + let cancellingInProgress = $state(false) async function continuouslyLoadQueuedJobs() { while (loadQueuedJobs) { @@ -40,7 +40,7 @@ let qjs = await JobService.listQueue({ workspace: $workspaceStore ?? '', orderDesc: false, - scriptPathExact: script.path + scriptPathExact: script?.path }) let loadingQueuedJobs: { status: 'running' | 'queued' @@ -71,12 +71,12 @@ cancellingInProgress = true await JobService.cancelPersistentQueuedJobs({ workspace: $workspaceStore ?? '', - path: script.path, + path: script?.path ?? '', requestBody: { reason: undefined } }) - sendUserToast(`All jobs cancelled for ${script.path}`) + sendUserToast(`All jobs cancelled for ${script?.path}`) cancellingInProgress = false } @@ -88,12 +88,12 @@ script = persistentScript! loadQueuedJobs = true continuouslyLoadQueuedJobs() - drawer.openDrawer?.() + drawer?.openDrawer?.() } async function exit() { loadQueuedJobs = false - drawer.closeDrawer?.() + drawer?.closeDrawer?.() } onDestroy(() => { @@ -117,51 +117,57 @@ > - Queued jobs for {script.path} + Queued jobs for {script?.path} - - Script Hash - Job ID - Status - Scheduled For - - - {#each queuedJobs as { jobId, status, scriptHash, scheduledFor }} - - - - {scriptHash} - - - - {jobId.substring(24)} - - - {#if status === 'running'} - - - - {:else} - - - - {/if} - - {scheduledFor} - - {/each} - + {#snippet headerRow()} + + Script Hash + Job ID + Status + Scheduled For + + {/snippet} + {#snippet body()} + + {#each queuedJobs as { jobId, status, scriptHash, scheduledFor }} + + + + {scriptHash} + + + + {jobId.substring(24)} + + + {#if status === 'running'} + + + + {:else} + + + + {/if} + + {scheduledFor} + + {/each} + + {/snippet} {#snippet actions()} diff --git a/frontend/src/lib/components/Popover.svelte b/frontend/src/lib/components/Popover.svelte index 1fa0a0d88d..07447b2e4a 100644 --- a/frontend/src/lib/components/Popover.svelte +++ b/frontend/src/lib/components/Popover.svelte @@ -43,10 +43,10 @@ onClick }: Props = $props() - const [popperRef, popperContent] = createPopperActions({ placement }) + const [popperRef, popperContent] = createPopperActions({ placement: untrack(() => placement) }) const popperOptions: PopperOptions<{}> = { - placement, + placement: untrack(() => placement), strategy: 'fixed', modifiers: [ { name: 'offset', options: { offset: [8, 8] } }, diff --git a/frontend/src/lib/components/PrefixedInput.svelte b/frontend/src/lib/components/PrefixedInput.svelte index c548418855..2a1dccf386 100644 --- a/frontend/src/lib/components/PrefixedInput.svelte +++ b/frontend/src/lib/components/PrefixedInput.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/RadioButton.svelte b/frontend/src/lib/components/RadioButton.svelte index efa9a62b40..c7e5dc8dce 100644 --- a/frontend/src/lib/components/RadioButton.svelte +++ b/frontend/src/lib/components/RadioButton.svelte @@ -1,13 +1,24 @@ @@ -28,7 +39,7 @@ class="sr-only" bind:group={value} aria-labelledby="memory-option-0-label" - on:click={() => dispatch('change', val)} + onclick={() => dispatch('change', val)} /> {#if typeof label !== 'string'} diff --git a/frontend/src/lib/components/Range.svelte b/frontend/src/lib/components/Range.svelte index 0e92ac72de..72129aada2 100644 --- a/frontend/src/lib/components/Range.svelte +++ b/frontend/src/lib/components/Range.svelte @@ -1,29 +1,47 @@ - + {#if max <= min} Impossible to display range: {`max (${max}) <= min (${min})`} + import { untrack } from 'svelte' import { GitSyncService } from '$lib/gen' import Select from './select/Select.svelte' @@ -32,7 +33,7 @@ }: Props = $props() // Track all loaded repositories across pages - let loadedRepositories = $state(initialRepositories) + let loadedRepositories = $state(untrack(() => initialRepositories)) let currentPage = $state(1) let isLoadingMore = $state(false) diff --git a/frontend/src/lib/components/Required.svelte b/frontend/src/lib/components/Required.svelte index 2163efa976..3ee1deec1a 100644 --- a/frontend/src/lib/components/Required.svelte +++ b/frontend/src/lib/components/Required.svelte @@ -1,12 +1,19 @@ {#if required} - * + * {:else if detail || detail != ''} - ({detail != '' ? `${detail}` : ''}) {/if} diff --git a/frontend/src/lib/components/ResourceEditor.svelte b/frontend/src/lib/components/ResourceEditor.svelte index 0ffed949d1..70aaf6a2ee 100644 --- a/frontend/src/lib/components/ResourceEditor.svelte +++ b/frontend/src/lib/components/ResourceEditor.svelte @@ -30,7 +30,6 @@ canSave?: boolean resource_type?: string | undefined path?: string - newResource?: boolean hidePath?: boolean onChange?: (args: { path: string; args: Record; description: string }) => void defaultValues?: Record | undefined @@ -40,7 +39,6 @@ canSave = $bindable(true), resource_type = $bindable(undefined), path = $bindable(''), - newResource = false, hidePath = false, onChange, defaultValues = undefined @@ -63,6 +61,7 @@ let resourceTypeInfo: ResourceType | undefined = $state(undefined) let editDescription = $state(false) let viewJsonSchema = $state(false) + let newResource = $derived(!path) const dispatch = createEventDispatcher() @@ -82,7 +81,7 @@ .map(([k, _]) => k) } - if (!newResource) { + if (!untrack(() => newResource)) { initEdit() } else if (resource_type) { loadResourceType() diff --git a/frontend/src/lib/components/ResourceEditorDrawer.svelte b/frontend/src/lib/components/ResourceEditorDrawer.svelte index 50db916f13..dae6943868 100644 --- a/frontend/src/lib/components/ResourceEditorDrawer.svelte +++ b/frontend/src/lib/components/ResourceEditorDrawer.svelte @@ -5,50 +5,44 @@ import { Loader2, Save } from 'lucide-svelte' - let drawer: Drawer - let canSave = true - let resource_type: string | undefined = undefined - let defaultValues: Record | undefined = undefined + let drawer: Drawer | undefined = $state() + let canSave = $state(true) + let resource_type: string | undefined = $state(undefined) + let defaultValues: Record | undefined = $state(undefined) let resourceEditor: { editResource: () => void; createResource: () => void } | undefined = - undefined + $state(undefined) - let path: string | undefined = undefined + let path: string | undefined = $state(undefined) - let newResource = false export async function initEdit(p: string): Promise { resource_type = undefined - newResource = false path = p - drawer.openDrawer?.() + drawer?.openDrawer?.() } export async function initNew( resourceType: string, nDefaultValues?: Record ): Promise { - newResource = true path = undefined resource_type = resourceType defaultValues = nDefaultValues - drawer.openDrawer?.() + drawer?.openDrawer?.() } - let mode: 'edit' | 'new' = newResource ? 'new' : 'edit' - - $: path ? (mode = 'edit') : (mode = 'new') + let mode: 'edit' | 'new' = $derived(!path ? 'new' : 'edit') {#await import('./ResourceEditor.svelte')} {:then Module} diff --git a/frontend/src/lib/components/ResourcePicker.svelte b/frontend/src/lib/components/ResourcePicker.svelte index 6806e60d3c..fddf9205f5 100644 --- a/frontend/src/lib/components/ResourcePicker.svelte +++ b/frontend/src/lib/components/ResourcePicker.svelte @@ -152,7 +152,7 @@ loading = false } - let previousResourceType = resourceType + let previousResourceType = untrack(() => resourceType) $effect(() => { $workspaceStore && resourceType diff --git a/frontend/src/lib/components/RunForm.svelte b/frontend/src/lib/components/RunForm.svelte index 969576a06b..da0c87a15f 100644 --- a/frontend/src/lib/components/RunForm.svelte +++ b/frontend/src/lib/components/RunForm.svelte @@ -15,7 +15,7 @@ import Popover from './meltComponents/Popover.svelte' import { Calendar, Check, CornerDownLeft } from 'lucide-svelte' import RunFormAdvancedPopup from './RunFormAdvancedPopup.svelte' - import { page } from '$app/stores' + import { page } from '$app/state' import { replaceState } from '$app/navigation' import JsonInputs from '$lib/components/JsonInputs.svelte' import { triggerableByAI } from '$lib/actions/triggerableByAI.svelte' @@ -108,7 +108,7 @@ nurl.hash = computeSharableHash(args) try { - replaceState(nurl.toString(), $page.state) + replaceState(nurl.toString(), page.state) } catch (e) { console.error(e) } diff --git a/frontend/src/lib/components/RunFormAdvancedPopup.svelte b/frontend/src/lib/components/RunFormAdvancedPopup.svelte index 7d6ef01bb2..399e55f772 100644 --- a/frontend/src/lib/components/RunFormAdvancedPopup.svelte +++ b/frontend/src/lib/components/RunFormAdvancedPopup.svelte @@ -8,7 +8,9 @@ import { WorkerService } from '$lib/gen' import DateTimeInput from './DateTimeInput.svelte' - export let runnable: + + interface Props { + runnable: | { summary?: string description?: string @@ -21,11 +23,18 @@ created_by?: string extra_perms?: Record } - | undefined + | undefined; + scheduledForStr: string | undefined; + invisible_to_owner: boolean | undefined; + overrideTag: string | undefined; + } - export let scheduledForStr: string | undefined - export let invisible_to_owner: boolean | undefined - export let overrideTag: string | undefined + let { + runnable, + scheduledForStr = $bindable(), + invisible_to_owner = $bindable(), + overrideTag = $bindable() + }: Props = $props(); loadWorkerGroups() async function loadWorkerGroups() { diff --git a/frontend/src/lib/components/RunsPage.svelte b/frontend/src/lib/components/RunsPage.svelte index d03495c052..5aee359a4a 100644 --- a/frontend/src/lib/components/RunsPage.svelte +++ b/frontend/src/lib/components/RunsPage.svelte @@ -96,8 +96,8 @@ let batchRerunOptionsIsOpen = $state(false) // Initialize path filter from route param if provided and not already set via query params - if (initialPath && !filters.val.path) { - filters.val.path = initialPath + if (untrack(() => initialPath) && !filters.val.path) { + filters.val.path = untrack(() => initialPath) } // Apply persistent toggle values from local storage if URL doesn't specify them diff --git a/frontend/src/lib/components/S3ObjectPicker.svelte b/frontend/src/lib/components/S3ObjectPicker.svelte index c70983ee83..1c461708cd 100644 --- a/frontend/src/lib/components/S3ObjectPicker.svelte +++ b/frontend/src/lib/components/S3ObjectPicker.svelte @@ -11,15 +11,19 @@ import S3FilePicker from './S3FilePicker.svelte' import FileUpload from './common/fileUpload/FileUpload.svelte' - export let value: any - export let editor: SimpleEditor | undefined = undefined + interface Props { + value: any + editor?: SimpleEditor | undefined + } + + let { value = $bindable(), editor = $bindable(undefined) }: Props = $props() const dispatch = createEventDispatcher() - let s3FilePicker: S3FilePicker - let s3FileUploadRawMode: false + let s3FilePicker: S3FilePicker | undefined = $state() + let s3FileUploadRawMode: boolean | undefined = $state() let el: HTMLTextAreaElement | undefined = undefined - let rawValue: string | undefined = undefined + let rawValue: string | undefined = $state(undefined) function evalValueToRaw() { rawValue = JSON.stringify(value, null, 2) diff --git a/frontend/src/lib/components/SaveInputsButton.svelte b/frontend/src/lib/components/SaveInputsButton.svelte index 414e5ff205..4bddde54ca 100644 --- a/frontend/src/lib/components/SaveInputsButton.svelte +++ b/frontend/src/lib/components/SaveInputsButton.svelte @@ -10,14 +10,25 @@ const dispatch = createEventDispatcher() - export let runnableId: string | undefined - export let runnableType: RunnableType | undefined - export let args: object - export let disabled: boolean = false - export let small: boolean | undefined = undefined - export let showTooltip: boolean | undefined = undefined + interface Props { + runnableId: string | undefined; + runnableType: RunnableType | undefined; + args: object; + disabled?: boolean; + small?: boolean | undefined; + showTooltip?: boolean | undefined; + } - let savingInputs = false + let { + runnableId, + runnableType, + args, + disabled = false, + small = undefined, + showTooltip = undefined + }: Props = $props(); + + let savingInputs = $state(false) async function saveInput(args: object) { savingInputs = true diff --git a/frontend/src/lib/components/SavedInputsPickerViewer.svelte b/frontend/src/lib/components/SavedInputsPickerViewer.svelte index 150e2b9b97..f033bbf4d9 100644 --- a/frontend/src/lib/components/SavedInputsPickerViewer.svelte +++ b/frontend/src/lib/components/SavedInputsPickerViewer.svelte @@ -1,20 +1,34 @@ - + {#snippet trigger({ isOpen })} - - + {/snippet} + {#snippet content()} { + onclick={() => { copyToClipboard(JSON.stringify(payloadData)) }} - on:keydown + onkeydown={bubble('keydown')} > {#if !objectViewerLoaded && payloadTooBigForPreview} @@ -158,5 +174,5 @@ {/if} - + {/snippet} diff --git a/frontend/src/lib/components/SchemaEditorProperty.svelte b/frontend/src/lib/components/SchemaEditorProperty.svelte index 611e178981..fa12138c0d 100644 --- a/frontend/src/lib/components/SchemaEditorProperty.svelte +++ b/frontend/src/lib/components/SchemaEditorProperty.svelte @@ -2,7 +2,11 @@ import type { SchemaProperty } from '$lib/common' import Badge from './common/badge/Badge.svelte' - export let property: SchemaProperty + interface Props { + property: SchemaProperty; + } + + let { property }: Props = $props(); diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 3de7ad3895..e4e166791b 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -157,7 +157,7 @@ let deployedBy: string | undefined = $state(undefined) // Author let confirmCallback: () => void = $state(() => {}) // What happens when user clicks `override` in warning let open: boolean = $state(false) // Is confirmation modal open - let args: Record = $state(initialArgs) // Test args input + let args: Record = $state(untrack(() => initialArgs)) // Test args input let selectedInputTab: 'main' | 'preprocessor' = $state('main') let hasPreprocessor = $state(false) let preserveOnBehalfOf = $state(false) @@ -170,12 +170,12 @@ let customOnBehalfOfEmail: string = $state('') let metadataOpen = $state( - !neverShowMeta && - (showMeta || - searchParams.get('metadata_open') == 'true' || + !untrack(() => neverShowMeta) && + (untrack(() => showMeta) || + untrack(() => searchParams).get('metadata_open') == 'true' || (initialPath == '' && - searchParams.get('state') == undefined && - searchParams.get('collab') == undefined)) + untrack(() => searchParams).get('state') == undefined && + untrack(() => searchParams).get('collab') == undefined)) ) let editor: Editor | undefined = $state(undefined) @@ -193,10 +193,15 @@ confirmDeploymentCallback(selectedTriggers) } - const primaryScheduleStore = writable(savedPrimarySchedule) // keep for legacy + const primaryScheduleStore = writable( + untrack(() => savedPrimarySchedule) + ) // keep for legacy const triggersCount = writable( - savedPrimarySchedule - ? { schedule_count: 1, primary_schedule: { schedule: savedPrimarySchedule.cron } } + untrack(() => savedPrimarySchedule) + ? { + schedule_count: 1, + primary_schedule: { schedule: untrack(() => savedPrimarySchedule)!.cron } + } : undefined ) const simplifiedPoll = writable(false) @@ -859,7 +864,7 @@ })() ) - setContext('disableTooltips', customUi?.disableTooltips === true) + setContext('disableTooltips', untrack(() => customUi)?.disableTooltips === true) function langToLanguage(lang: SupportedLanguage | 'docker' | 'bunnative'): SupportedLanguage { if (lang == 'docker') { @@ -1672,8 +1677,10 @@ /> {:else if script.on_behalf_of_email && !canPreserve} - Currently: {originalOnBehalfOfEmail ?? script.on_behalf_of_email}. - Will be set to {$userStore?.email} on deploy (requires admin or wm_deployers group to override) + Currently: {originalOnBehalfOfEmail ?? script.on_behalf_of_email}. Will be set to {$userStore?.email} on + deploy (requires admin or wm_deployers group to override) {/if} diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte index 0f1e1d8a6e..f310010c18 100644 --- a/frontend/src/lib/components/ScriptEditor.svelte +++ b/frontend/src/lib/components/ScriptEditor.svelte @@ -123,7 +123,7 @@ lastDeployedCode?: string | undefined disableAi?: boolean assets?: AssetWithAltAccessType[] - editor_bar_right?: import('svelte').Snippet + editorBarRight?: import('svelte').Snippet enablePreprocessorSnippet?: boolean } @@ -155,7 +155,7 @@ lastDeployedCode = undefined, disableAi = false, assets = $bindable(), - editor_bar_right, + editorBarRight, enablePreprocessorSnippet = false }: Props = $props() @@ -883,7 +883,7 @@ } } - setContext('disableTooltips', customUi?.disableTooltips === true) + setContext('disableTooltips', untrack(() => customUi)?.disableTooltips === true) let codePanelSize = $state(70) let testPanelSize = $state(30) @@ -1042,7 +1042,7 @@ bind:showHistoryDrawer > {#snippet right()} - {@render editor_bar_right?.()} + {@render editorBarRight?.()} {/snippet} {/if} diff --git a/frontend/src/lib/components/ScriptPicker.svelte b/frontend/src/lib/components/ScriptPicker.svelte index 5fa0618edd..803684f49e 100644 --- a/frontend/src/lib/components/ScriptPicker.svelte +++ b/frontend/src/lib/components/ScriptPicker.svelte @@ -52,7 +52,7 @@ let lang: SupportedLanguage | undefined = $state() let options: [[string, any, any, string | undefined]] = [['Script', 'script', Code2, undefined]] - allowFlow && options.push(['Flow', 'flow', FlowIcon, '#14b8a6']) + untrack(() => allowFlow) && options.push(['Flow', 'flow', FlowIcon, '#14b8a6']) const dispatch = createEventDispatcher() async function loadItems(): Promise { diff --git a/frontend/src/lib/components/ScriptWrapper.svelte b/frontend/src/lib/components/ScriptWrapper.svelte index 5e53dc09f3..eec781ce77 100644 --- a/frontend/src/lib/components/ScriptWrapper.svelte +++ b/frontend/src/lib/components/ScriptWrapper.svelte @@ -1,11 +1,12 @@ diff --git a/frontend/src/lib/components/Scrollable.svelte b/frontend/src/lib/components/Scrollable.svelte index 37e3ae2933..7c34b3cbe1 100644 --- a/frontend/src/lib/components/Scrollable.svelte +++ b/frontend/src/lib/components/Scrollable.svelte @@ -2,14 +2,19 @@ import { onMount, onDestroy } from 'svelte' import { twMerge } from 'tailwind-merge' - let isAtBottom: boolean = false - let isScrollable = false + let isAtBottom: boolean = $state(false) + let isScrollable = $state(false) - export let id: string | null | undefined = undefined - export let scrollableClass: string = '' - export let shiftedShadow: boolean = false + interface Props { + id?: string | null | undefined + scrollableClass?: string + shiftedShadow?: boolean + children?: import('svelte').Snippet + } + + let { id = undefined, scrollableClass = '', shiftedShadow = false, children }: Props = $props() let mutationObserver: MutationObserver - let el: HTMLDivElement + let el: HTMLDivElement | undefined = $state() function handleScroll(event) { const scrollableElement = event.target @@ -20,7 +25,8 @@ } function checkIfScrollable(el) { - return el.scrollHeight > el.clientHeight + if (!el) return false + return el?.scrollHeight > el?.clientHeight } function observeScrollability(el) { @@ -33,7 +39,7 @@ } export function scrollIntoView(top: number) { - el.scrollTo({ top, behavior: 'smooth' }) + el?.scrollTo({ top, behavior: 'smooth' }) } onMount(() => { observeScrollability(el) @@ -45,8 +51,8 @@ - - + + {@render children?.()} {#if !isAtBottom && isScrollable} opts)) function filterItems() { let trimmed = filter.trim() diff --git a/frontend/src/lib/components/ServiceLogsInner.svelte b/frontend/src/lib/components/ServiceLogsInner.svelte index 0f4f923cd6..abcffa32ef 100644 --- a/frontend/src/lib/components/ServiceLogsInner.svelte +++ b/frontend/src/lib/components/ServiceLogsInner.svelte @@ -22,7 +22,7 @@ import SplitPanesOrColumnOnMobile from './splitPanes/SplitPanesOrColumnOnMobile.svelte' import Select from './select/Select.svelte' import { goto } from '$lib/navigation' - import { page } from '$app/stores' + import { page } from '$app/state' import { watch } from 'runed' interface Props { @@ -169,13 +169,13 @@ type Selected = { mode: string; workerGroup: string; hostname: string } let initialSelected = - $page.url.searchParams.get('mode') && - $page.url.searchParams.get('workerGroup') && - $page.url.searchParams.get('hostname') + page.url.searchParams.get('mode') && + page.url.searchParams.get('workerGroup') && + page.url.searchParams.get('hostname') ? { - mode: $page.url.searchParams.get('mode')!, - workerGroup: $page.url.searchParams.get('workerGroup')!, - hostname: $page.url.searchParams.get('hostname')! + mode: page.url.searchParams.get('mode')!, + workerGroup: page.url.searchParams.get('workerGroup')!, + hostname: page.url.searchParams.get('hostname')! } : undefined let selected: Selected | undefined = $state(initialSelected) @@ -663,7 +663,7 @@ { + onClick={() => { let logLineNumber = document.line_number[0] let logFile = document.file_name[0] let host = document.host[0] diff --git a/frontend/src/lib/components/ShareModal.svelte b/frontend/src/lib/components/ShareModal.svelte index c8c69106ed..10cf5f09e0 100644 --- a/frontend/src/lib/components/ShareModal.svelte +++ b/frontend/src/lib/components/ShareModal.svelte @@ -159,12 +159,14 @@ {/if} {#if acls?.length > 0} - - - owner - - - + + {#snippet headerRow()} + + owner + + + + {/snippet} {#snippet body()} {#each acls as [owner, write]} diff --git a/frontend/src/lib/components/SimpleEditor.svelte b/frontend/src/lib/components/SimpleEditor.svelte index 2fdd14e3f9..31da7fd802 100644 --- a/frontend/src/lib/components/SimpleEditor.svelte +++ b/frontend/src/lib/components/SimpleEditor.svelte @@ -130,7 +130,7 @@ const dispatch = createEventDispatcher() - const uri = `file:///${hash}.${langToExt(lang)}` + const uri = `file:///${untrack(() => hash)}.${langToExt(untrack(() => lang))}` export function getCode(): string { if (valueAfterDispose != undefined) { diff --git a/frontend/src/lib/components/Slider.svelte b/frontend/src/lib/components/Slider.svelte index c2ca0abbdd..e3269cde09 100644 --- a/frontend/src/lib/components/Slider.svelte +++ b/frontend/src/lib/components/Slider.svelte @@ -5,10 +5,21 @@ import Tooltip from './Tooltip.svelte' import { twMerge } from 'tailwind-merge' - export let text: string - export let tooltip: string | undefined = undefined - export let view = false - export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md' + interface Props { + text: string; + tooltip?: string | undefined; + view?: boolean; + size?: 'xs' | 'sm' | 'md' | 'lg'; + children?: import('svelte').Snippet; + } + + let { + text, + tooltip = undefined, + view = $bindable(false), + size = 'md', + children + }: Props = $props(); {#if view} - + {@render children?.()} {/if} diff --git a/frontend/src/lib/components/StringTypeNarrowing.svelte b/frontend/src/lib/components/StringTypeNarrowing.svelte index bce364d44f..7d84b4c4fc 100644 --- a/frontend/src/lib/components/StringTypeNarrowing.svelte +++ b/frontend/src/lib/components/StringTypeNarrowing.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/Summary.svelte b/frontend/src/lib/components/Summary.svelte index 42d0b48ba5..1b4c3f2c2e 100644 --- a/frontend/src/lib/components/Summary.svelte +++ b/frontend/src/lib/components/Summary.svelte @@ -2,8 +2,12 @@ import { Pen } from 'lucide-svelte' import TextInput from './text_input/TextInput.svelte' - export let value: string - export let disabled = false + interface Props { + value: string; + disabled?: boolean; + } + + let { value = $bindable(), disabled = false }: Props = $props(); function blur(e: KeyboardEvent) { e.key === 'Enter' && (e?.target as any)?.blur() diff --git a/frontend/src/lib/components/SupabaseConnect.svelte b/frontend/src/lib/components/SupabaseConnect.svelte index d16960ffbc..e44399ee84 100644 --- a/frontend/src/lib/components/SupabaseConnect.svelte +++ b/frontend/src/lib/components/SupabaseConnect.svelte @@ -1,4 +1,6 @@ @@ -120,7 +124,7 @@ {#each databases as database} { + onclick={() => { selectedDatabase = database step = 'resource' diff --git a/frontend/src/lib/components/SuperadminSettings.svelte b/frontend/src/lib/components/SuperadminSettings.svelte index f9b446b04e..c6cbe9f421 100644 --- a/frontend/src/lib/components/SuperadminSettings.svelte +++ b/frontend/src/lib/components/SuperadminSettings.svelte @@ -98,15 +98,17 @@ → {uptodateVersion} {/if} - - {#if isCloudHosted()} - The cloud version is updated daily. - {:else} - How to update? - - docker: docker compose up -d - - helm - {/if} - + {#snippet text()} + + {#if isCloudHosted()} + The cloud version is updated daily. + {:else} + How to update? + - docker: docker compose up -d + - helm + {/if} + + {/snippet} {/snippet} {#snippet actions()} diff --git a/frontend/src/lib/components/SuperadminSettingsInner.svelte b/frontend/src/lib/components/SuperadminSettingsInner.svelte index 4d6b0e33f1..1f33e768d8 100644 --- a/frontend/src/lib/components/SuperadminSettingsInner.svelte +++ b/frontend/src/lib/components/SuperadminSettingsInner.svelte @@ -8,7 +8,7 @@ import { sendUserToast } from '$lib/toast' import { base } from '$lib/base' import SearchItems from './SearchItems.svelte' - import { page } from '$app/stores' + import { page } from '$app/state' import { goto as gotoUrl } from '$app/navigation' import Version from './Version.svelte' import Uptodate from './Uptodate.svelte' @@ -50,9 +50,9 @@ } = $props() function removeHash() { - const index = $page.url.href.lastIndexOf('#') + const index = page.url.href.lastIndexOf('#') if (index === -1) return - const hashRemoved = $page.url.href.slice(0, index) + const hashRemoved = page.url.href.slice(0, index) gotoUrl(hashRemoved) } diff --git a/frontend/src/lib/components/TableCustom.svelte b/frontend/src/lib/components/TableCustom.svelte index e40a2c9706..a508d48c8f 100644 --- a/frontend/src/lib/components/TableCustom.svelte +++ b/frontend/src/lib/components/TableCustom.svelte @@ -1,37 +1,53 @@ - + - + {@render headerRow?.()} - + {@render body?.()} {#if paginated} dispatch('next')} + onclick={() => dispatch('next')} > Next dispatch('previous')} + onclick={() => dispatch('previous')} > Previous diff --git a/frontend/src/lib/components/TemplateEditor.svelte b/frontend/src/lib/components/TemplateEditor.svelte index f3ad00ffc3..8046e6ec97 100644 --- a/frontend/src/lib/components/TemplateEditor.svelte +++ b/frontend/src/lib/components/TemplateEditor.svelte @@ -412,7 +412,7 @@ const lang = 'template' const dispatch = createEventDispatcher() - const uri = `file:///${hash}.ts` + const uri = `file:///${untrack(() => hash)}.ts` export function insertAtCursor(code: string): void { if (editor) { diff --git a/frontend/src/lib/components/TestConnection.svelte b/frontend/src/lib/components/TestConnection.svelte index 576bbc9334..7c59a2a324 100644 --- a/frontend/src/lib/components/TestConnection.svelte +++ b/frontend/src/lib/components/TestConnection.svelte @@ -7,10 +7,19 @@ import { workspaceStore } from '$lib/stores' import { tryEvery } from '$lib/utils' - export let workspaceOverride: string | undefined = undefined - export let resourceType: string | undefined - export let args: Record | any = {} - export let buttonTextOverride: string | undefined = undefined + interface Props { + workspaceOverride?: string | undefined; + resourceType: string | undefined; + args?: Record | any; + buttonTextOverride?: string | undefined; + } + + let { + workspaceOverride = undefined, + resourceType, + args = {}, + buttonTextOverride = undefined + }: Props = $props(); const scripts: { [key: string]: { @@ -166,7 +175,7 @@ export async function main(bucket: any) { } } - let loading = false + let loading = $state(false) async function testConnection() { if (!resourceType) return loading = true diff --git a/frontend/src/lib/components/Toast.svelte b/frontend/src/lib/components/Toast.svelte index 13e857ed6f..034887235e 100644 --- a/frontend/src/lib/components/Toast.svelte +++ b/frontend/src/lib/components/Toast.svelte @@ -82,14 +82,14 @@ } }) - let color = classes[type] + let color = classes[untrack(() => type)] let containerClass = { success: 'toast-success', error: 'toast-error', info: 'toast-info', warning: 'toast-warning' - }[type] + }[untrack(() => type)] let Icon = $derived(icons[type]) diff --git a/frontend/src/lib/components/Toggle.svelte b/frontend/src/lib/components/Toggle.svelte index 6b502bcbfa..4ae37d325f 100644 --- a/frontend/src/lib/components/Toggle.svelte +++ b/frontend/src/lib/components/Toggle.svelte @@ -3,7 +3,7 @@ const bubble = createBubbler() import { classNames } from '$lib/utils' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' import { twMerge } from 'tailwind-merge' import Tooltip from './Tooltip.svelte' import { AlertTriangle } from 'lucide-svelte' @@ -54,7 +54,7 @@ }: Props = $props() const dispatch = createEventDispatcher<{ change: boolean }>() - const bothOptions = Boolean(options.left) && Boolean(options.right) + const bothOptions = Boolean(untrack(() => options).left) && Boolean(untrack(() => options).right) import { urlize } from '$lib/utils' - export let text: string - $: parsed = text ? urlize(text, 'html') : '' + interface Props { + text: string; + } + + let { text }: Props = $props(); + let parsed = $derived(text ? urlize(text, 'html') : '') {@html parsed} diff --git a/frontend/src/lib/components/Version.svelte b/frontend/src/lib/components/Version.svelte index 9406bed01f..aa0b58624d 100644 --- a/frontend/src/lib/components/Version.svelte +++ b/frontend/src/lib/components/Version.svelte @@ -1,7 +1,7 @@ {#if flow_status} diff --git a/frontend/src/lib/components/ZitadelSetting.svelte b/frontend/src/lib/components/ZitadelSetting.svelte index ce8b879db9..430c4c588c 100644 --- a/frontend/src/lib/components/ZitadelSetting.svelte +++ b/frontend/src/lib/components/ZitadelSetting.svelte @@ -1,16 +1,20 @@ - + - import { setContext } from 'svelte' + import { setContext, untrack } from 'svelte' import type { Writable } from 'svelte/store' import type { GroupContext } from '../types' @@ -11,7 +11,10 @@ let { context, id, children }: Props = $props() - setContext('GroupContext', { id, context }) + setContext('GroupContext', { + id: untrack(() => id), + context: untrack(() => context) + }) {@render children?.()} diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index 547fff4723..50e815c917 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -72,17 +72,25 @@ const listInputs: ListInputs | undefined = getContext('ListInputs') let resolvedConfig = $state( - initConfig(components['buttoncomponent'].initialData.configuration, configuration) + initConfig( + components['buttoncomponent'].initialData.configuration, + untrack(() => configuration) + ) ) - let outputs = initOutput($worldStore, id, { - result: undefined, - loading: false, - jobId: undefined - }) + let outputs = initOutput( + $worldStore, + untrack(() => id), + { + result: undefined, + loading: false, + jobId: undefined + } + ) - if (controls) { - $componentControl[id] = controls + const untrackedControls = untrack(() => controls) + if (untrackedControls) { + $componentControl[untrack(() => id)] = untrackedControls } let runnableComponent: RunnableComponent | undefined = $state() @@ -203,7 +211,12 @@ let loading = $state(false) let backgroundClickFeedback = $state(false) - let css = $state(initCss($app.css?.buttoncomponent, customCss)) + let css = $state( + initCss( + $app.css?.buttoncomponent, + untrack(() => customCss) + ) + ) $effect(() => { errorHandledByComponent = resolvedConfig?.onError?.selected !== 'errorOverlay' }) diff --git a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte index 68064c0136..e7e606d8f3 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte @@ -1,6 +1,6 @@ {#each Object.keys(components['alertcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppBarChart.svelte b/frontend/src/lib/components/apps/components/display/AppBarChart.svelte index f873e149bb..f8d78cadeb 100644 --- a/frontend/src/lib/components/apps/components/display/AppBarChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppBarChart.svelte @@ -11,7 +11,7 @@ Title, Tooltip } from 'chart.js' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { Bar, Line } from '$lib/components/chartjs-wrappers/chartJs' import { initConfig, initOutput } from '../../editor/appUtils' import type { AppInput } from '../../inputType' @@ -43,10 +43,10 @@ const { app, worldStore } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['barchartcomponent'].initialData.configuration, configuration) + initConfig(components['barchartcomponent'].initialData.configuration, untrack(() => configuration)) ) - let outputs = initOutput($worldStore, id, { + let outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -119,7 +119,7 @@ } }) - let css = $state(initCss($app.css?.barchartcomponent, customCss)) + let css = $state(initCss($app.css?.barchartcomponent, untrack(() => customCss))) {#each Object.keys(components['barchartcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte b/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte index 4b96de346e..f92d42f12a 100644 --- a/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte +++ b/frontend/src/lib/components/apps/components/display/AppCarouselList.svelte @@ -39,12 +39,12 @@ const { app, focusedGrid, selectedComponent, worldStore, connectingInput, componentControl } = getContext('AppViewerContext') - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect.pre(() => { render && !everRender && (everRender = true) }) - let outputs = initOutput($worldStore, id, { + let outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, inputs: {}, @@ -52,7 +52,7 @@ }) const resolvedConfig = $state( - initConfig(components['carousellistcomponent'].initialData.configuration, configuration) + initConfig(components['carousellistcomponent'].initialData.configuration, untrack(() => configuration)) ) function onFocus() { @@ -62,7 +62,7 @@ } } - let css = $state(initCss($app.css?.carousellistcomponent, customCss)) + let css = $state(initCss($app.css?.carousellistcomponent, untrack(() => customCss))) let result: any[] | undefined = $state(undefined) let inputs = $state({}) @@ -105,7 +105,7 @@ currentPageIndex != undefined && untrack(() => handleIndexChange()) }) - $componentControl[id] = { + $componentControl[untrack(() => id)] = { setSelectedIndex: (index: number) => { if (Array.isArray(result) && index >= 0 && index < result.length) { currentPageIndex = index diff --git a/frontend/src/lib/components/apps/components/display/AppChartJs.svelte b/frontend/src/lib/components/apps/components/display/AppChartJs.svelte index 7ac9cdb9b9..58ef1723fa 100644 --- a/frontend/src/lib/components/apps/components/display/AppChartJs.svelte +++ b/frontend/src/lib/components/apps/components/display/AppChartJs.svelte @@ -5,7 +5,7 @@ import type { AppInput } from '../../inputType' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initConfig, initOutput } from '../../editor/appUtils' import { components } from '../../editor/component' import ResolveConfig from '../helpers/ResolveConfig.svelte' @@ -32,7 +32,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -42,7 +42,7 @@ let result: undefined = $state(undefined) const resolvedConfig = $state( - initConfig(components['chartjscomponent'].initialData.configuration, configuration) + initConfig(components['chartjscomponent'].initialData.configuration, untrack(() => configuration)) ) let options = $derived({ responsive: true, @@ -51,7 +51,7 @@ ...(resolvedConfig.options ?? {}) } as ChartOptions) - let css = $state(initCss($app.css?.chartjscomponent, customCss)) + let css = $state(initCss($app.css?.chartjscomponent, untrack(() => customCss))) {#each Object.keys(components['chartjscomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte b/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte index d4b35a97f2..2833b84612 100644 --- a/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte +++ b/frontend/src/lib/components/apps/components/display/AppChartJsV2.svelte @@ -10,7 +10,7 @@ RichConfigurations } from '../../types' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initConfig, initOutput } from '../../editor/appUtils' import { components } from '../../editor/component' import ResolveConfig from '../helpers/ResolveConfig.svelte' @@ -51,7 +51,7 @@ const { app, worldStore, darkMode } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -61,7 +61,7 @@ let result: undefined = $state(undefined) const resolvedConfig = $state( - initConfig(components['chartjscomponent'].initialData.configuration, configuration) + initConfig(components['chartjscomponent'].initialData.configuration, untrack(() => configuration)) ) function hasScales() { @@ -110,7 +110,7 @@ : result ) - let css = $state(initCss($app.css?.chartjscomponent, customCss)) + let css = $state(initCss($app.css?.chartjscomponent, untrack(() => customCss))) {#if datasets} diff --git a/frontend/src/lib/components/apps/components/display/AppChat.svelte b/frontend/src/lib/components/apps/components/display/AppChat.svelte index 49e6f5d2a1..15bdc7bc57 100644 --- a/frontend/src/lib/components/apps/components/display/AppChat.svelte +++ b/frontend/src/lib/components/apps/components/display/AppChat.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte b/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte index 5b3fd64173..d2831f76a3 100644 --- a/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte +++ b/frontend/src/lib/components/apps/components/display/AppDisplayComponentByJobId.svelte @@ -38,10 +38,10 @@ const requireHtmlApproval = getContext(IS_APP_PUBLIC_CONTEXT_KEY) let resolvedConfig = $state( - initConfig(components['jobiddisplaycomponent'].initialData.configuration, configuration) + initConfig(components['jobiddisplaycomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, jobId: undefined as string | undefined @@ -49,7 +49,7 @@ initializing = false - let css = $state(initCss($app.css?.jobiddisplaycomponent, customCss)) + let css = $state(initCss($app.css?.jobiddisplaycomponent, untrack(() => customCss))) let jobLoader: JobLoader | undefined = $state(undefined) let testIsLoading: boolean = $state(false) diff --git a/frontend/src/lib/components/apps/components/display/AppDownload.svelte b/frontend/src/lib/components/apps/components/display/AppDownload.svelte index 0f38afe1db..48a8101f1b 100644 --- a/frontend/src/lib/components/apps/components/display/AppDownload.svelte +++ b/frontend/src/lib/components/apps/components/display/AppDownload.svelte @@ -36,14 +36,14 @@ }: Props = $props() const resolvedConfig = $state( - initConfig(components['downloadcomponent'].initialData.configuration, configuration) + initConfig(components['downloadcomponent'].initialData.configuration, untrack(() => configuration)) ) const { app, worldStore, appPath, workspace, isEditor } = getContext('AppViewerContext') //used so that we can count number of outputs setup for first refresh - initOutput($worldStore, id, {}) + initOutput($worldStore, untrack(() => id), {}) let beforeIconComponent: any = $state() let afterIconComponent: any = $state() @@ -106,7 +106,7 @@ } } - let css = $state(initCss($app.css?.downloadcomponent, customCss)) + let css = $state(initCss($app.css?.downloadcomponent, untrack(() => customCss))) $effect(() => { resolvedConfig.beforeIcon && beforeIconComponent && untrack(() => handleBeforeIcon()) }) diff --git a/frontend/src/lib/components/apps/components/display/AppHtml.svelte b/frontend/src/lib/components/apps/components/display/AppHtml.svelte index fa8f49b3a4..3975a54cf5 100644 --- a/frontend/src/lib/components/apps/components/display/AppHtml.svelte +++ b/frontend/src/lib/components/apps/components/display/AppHtml.svelte @@ -1,5 +1,5 @@ {#each Object.keys(css ?? {}) as key (key)} @@ -46,6 +46,7 @@ {/each} {#if render} + { if ($mode !== 'preview') { diff --git a/frontend/src/lib/components/apps/components/display/AppIcon.svelte b/frontend/src/lib/components/apps/components/display/AppIcon.svelte index c4e6862c04..c97f005dc6 100644 --- a/frontend/src/lib/components/apps/components/display/AppIcon.svelte +++ b/frontend/src/lib/components/apps/components/display/AppIcon.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte b/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte index eace729280..d9b4ac4c0a 100644 --- a/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte +++ b/frontend/src/lib/components/apps/components/display/AppJobIdLogComponent.svelte @@ -37,10 +37,10 @@ const { app, worldStore, workspace } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['jobidlogcomponent'].initialData.configuration, configuration) + initConfig(components['jobidlogcomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, jobId: undefined @@ -48,7 +48,7 @@ initializing = false - let css = $state(initCss($app.css?.jobidlogcomponent, customCss)) + let css = $state(initCss($app.css?.jobidlogcomponent, untrack(() => customCss))) let jobLoader: JobLoader | undefined = $state(undefined) let testIsLoading: boolean = $state(false) diff --git a/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte b/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte index ecee9c1199..9cf5b59b6e 100644 --- a/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte +++ b/frontend/src/lib/components/apps/components/display/AppJobProgressBar.svelte @@ -38,10 +38,10 @@ const { app, worldStore, workspace } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['jobprogressbarcomponent'].initialData.configuration, configuration) + initConfig(components['jobprogressbarcomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, jobId: undefined @@ -49,7 +49,7 @@ initializing = false - let css = $state(initCss($app.css?.jobprogressbarcomponent, customCss)) + let css = $state(initCss($app.css?.jobprogressbarcomponent, untrack(() => customCss))) let jobLoader: JobLoader | undefined = $state(undefined) let testIsLoading: boolean = $state(false) diff --git a/frontend/src/lib/components/apps/components/display/AppMap.svelte b/frontend/src/lib/components/apps/components/display/AppMap.svelte index a630226d7b..1f04716110 100644 --- a/frontend/src/lib/components/apps/components/display/AppMap.svelte +++ b/frontend/src/lib/components/apps/components/display/AppMap.svelte @@ -1,7 +1,7 @@ {#each Object.keys(components['navbarcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppPdf.svelte b/frontend/src/lib/components/apps/components/display/AppPdf.svelte index e31cb4ae65..b5d498ca37 100644 --- a/frontend/src/lib/components/apps/components/display/AppPdf.svelte +++ b/frontend/src/lib/components/apps/components/display/AppPdf.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/display/AppPieChart.svelte b/frontend/src/lib/components/apps/components/display/AppPieChart.svelte index d7fde24dc9..ca5671b342 100644 --- a/frontend/src/lib/components/apps/components/display/AppPieChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppPieChart.svelte @@ -16,7 +16,7 @@ import InputValue from '../helpers/InputValue.svelte' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initOutput } from '../../editor/appUtils' import { twMerge } from 'tailwind-merge' import ResolveStyle from '../helpers/ResolveStyle.svelte' @@ -41,7 +41,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -87,7 +87,7 @@ ] }) - let css = $state(initCss($app.css?.piechartcomponent, customCss)) + let css = $state(initCss($app.css?.piechartcomponent, untrack(() => customCss))) {#each Object.keys(css ?? {}) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte b/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte index 5cdccb672d..c0308458ad 100644 --- a/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte +++ b/frontend/src/lib/components/apps/components/display/AppRecomputeAll.svelte @@ -36,16 +36,16 @@ getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['recomputeallcomponent'].initialData.configuration, configuration) + initConfig(components['recomputeallcomponent'].initialData.configuration, untrack(() => configuration)) ) - initOutput($worldStore, id, { + initOutput($worldStore, untrack(() => id), { loading: undefined }) initializing = false - let css = $state(initCss($app.css?.recomputeallcomponent, customCss)) + let css = $state(initCss($app.css?.recomputeallcomponent, untrack(() => customCss))) function handleRefreshInterval() { if (resolvedConfig.defaultRefreshInterval !== undefined) { diff --git a/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte b/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte index dd0d03e70a..ae139ea7c5 100644 --- a/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte +++ b/frontend/src/lib/components/apps/components/display/AppScatterChart.svelte @@ -17,7 +17,7 @@ import InputValue from '../helpers/InputValue.svelte' import type { ChartOptions, ChartData } from 'chart.js' import { initCss } from '../../utils' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' import { initOutput } from '../../editor/appUtils' import { twMerge } from 'tailwind-merge' @@ -47,7 +47,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -91,7 +91,7 @@ datasets: result ?? [] } as ChartData<'scatter', (number | Point)[], unknown>) - let css = $state(initCss($app.css?.scatterchartcomponent, customCss)) + let css = $state(initCss($app.css?.scatterchartcomponent, untrack(() => customCss))) {#each Object.keys(css ?? {}) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/AppStatCard.svelte b/frontend/src/lib/components/apps/components/display/AppStatCard.svelte index f773e75db0..fb6d665408 100644 --- a/frontend/src/lib/components/apps/components/display/AppStatCard.svelte +++ b/frontend/src/lib/components/apps/components/display/AppStatCard.svelte @@ -27,12 +27,12 @@ const { app, worldStore } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['statcomponent'].initialData.configuration, configuration) + initConfig(components['statcomponent'].initialData.configuration, untrack(() => configuration)) ) - initOutput($worldStore, id, {}) + initOutput($worldStore, untrack(() => id), {}) - let css = $state(initCss($app.css?.statcomponent, customCss)) + let css = $state(initCss($app.css?.statcomponent, untrack(() => customCss))) let iconComponent: any = $state() diff --git a/frontend/src/lib/components/apps/components/display/AppText.svelte b/frontend/src/lib/components/apps/components/display/AppText.svelte index a7f98089f8..03aae9be37 100644 --- a/frontend/src/lib/components/apps/components/display/AppText.svelte +++ b/frontend/src/lib/components/apps/components/display/AppText.svelte @@ -43,7 +43,10 @@ }: Props = $props() let resolvedConfig = $state( - initConfig(components['textcomponent'].initialData.configuration, configuration) + initConfig( + components['textcomponent'].initialData.configuration, + untrack(() => configuration) + ) ) function onEditorMode() { @@ -53,29 +56,40 @@ const { app, worldStore, mode, componentControl } = getContext('AppViewerContext') - let css = $state(initCss($app.css?.textcomponent, customCss)) + let css = $state( + initCss( + $app.css?.textcomponent, + untrack(() => customCss) + ) + ) let result: string | undefined = $state(undefined) + const untrackedComponentInput = untrack(() => componentInput) if ( - componentInput?.type == 'template' || - (componentInput?.type == 'templatev2' && !isCodeInjection(componentInput.eval)) + untrackedComponentInput?.type == 'template' || + (untrackedComponentInput?.type == 'templatev2' && + !isCodeInjection(untrackedComponentInput.eval)) ) { - result = componentInput.eval + result = untrackedComponentInput.eval initializing = false } - $componentControl[id] = { - ...$componentControl[id], + $componentControl[untrack(() => id)] = { + ...$componentControl[untrack(() => id)], setValue(value: string) { result = value } } - const outputs = initOutput($worldStore, id, { - result: untrack(() => result), - loading: initializing - }) + const outputs = initOutput( + $worldStore, + untrack(() => id), + { + result: untrack(() => result), + loading: initializing + } + ) function getComponent() { switch (resolvedConfig.style) { diff --git a/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte b/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte index 638d68d71e..85582683df 100644 --- a/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte +++ b/frontend/src/lib/components/apps/components/display/AppTimeseries.svelte @@ -21,7 +21,7 @@ import InputValue from '../helpers/InputValue.svelte' import type { ChartOptions, ChartData } from 'chart.js' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initCss } from '../../utils' import { initOutput } from '../../editor/appUtils' import { twMerge } from 'tailwind-merge' @@ -47,7 +47,7 @@ const { app, worldStore } = getContext('AppViewerContext') - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -105,7 +105,7 @@ datasets: result ?? [] } as ChartData<'scatter', (number | Point)[], unknown>) - let css = $state(initCss($app.css?.timeseriescomponent, customCss)) + let css = $state(initCss($app.css?.timeseriescomponent, untrack(() => customCss))) {#each Object.keys(css ?? {}) as key (key)} diff --git a/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte b/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte index 3f7de3b5ab..95aeef0c32 100644 --- a/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte +++ b/frontend/src/lib/components/apps/components/display/InsertRowDrawerButton.svelte @@ -25,7 +25,7 @@ { + onkeydown={(e) => { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { onConfirm() } diff --git a/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte b/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte index 82cd9f805f..13ad56d850 100644 --- a/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte +++ b/frontend/src/lib/components/apps/components/display/PlotlyHtml.svelte @@ -30,10 +30,10 @@ const { worldStore, darkMode } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['plotlycomponent'].initialData.configuration, configuration) + initConfig(components['plotlycomponent'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -125,6 +125,7 @@ {/if} + diff --git a/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte b/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte index f6ed334205..87f47af837 100644 --- a/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte +++ b/frontend/src/lib/components/apps/components/display/PlotlyHtmlV2.svelte @@ -34,10 +34,10 @@ const { worldStore, darkMode } = getContext('AppViewerContext') let resolvedConfig = $state( - initConfig(components['plotlycomponentv2'].initialData.configuration, configuration) + initConfig(components['plotlycomponentv2'].initialData.configuration, untrack(() => configuration)) ) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false }) @@ -207,6 +207,7 @@ {/if} + diff --git a/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte b/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte index e5307b4d15..0ab7b2795c 100644 --- a/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte +++ b/frontend/src/lib/components/apps/components/display/ResolveNavbarItemPath.svelte @@ -1,4 +1,5 @@ {#each Object.keys(components['checkboxcomponent'].initialData.configuration) as key (key)} diff --git a/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte b/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte index 9566f39866..62eedc3fc6 100644 --- a/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte +++ b/frontend/src/lib/components/apps/components/inputs/AppCodeInputComponent.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte b/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte index d42fdc3ba5..62b785c486 100644 --- a/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppDecisionTree.svelte @@ -51,7 +51,7 @@ untrack(() => (counter += 1)) }) - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect.pre(() => { render && !everRender && (everRender = true) }) @@ -66,11 +66,11 @@ debuggingComponents } = getContext('AppViewerContext') - let css = $state(initCss($app.css?.conditionalwrapper, customCss)) + let css = $state(initCss($app.css?.conditionalwrapper, untrack(() => customCss))) let selectedConditionIndex = 0 - let currentNodeId = $state(getFirstNode(nodes)?.id ?? '') + let currentNodeId = $state(getFirstNode(untrack(() => nodes))?.id ?? '') - let outputs = initOutput($worldStore, id, { + let outputs = initOutput($worldStore, untrack(() => id), { currentNodeId: untrack(() => currentNodeId), currentNodeIndex: selectedConditionIndex }) @@ -154,7 +154,7 @@ } } - $componentControl[id] = { + $componentControl[untrack(() => id)] = { setTab: (conditionIndex: number) => { if (conditionIndex !== -1) { onFocus(conditionIndex) diff --git a/frontend/src/lib/components/apps/components/layout/AppDivider.svelte b/frontend/src/lib/components/apps/components/layout/AppDivider.svelte index 97a698dd60..af68c3ad55 100644 --- a/frontend/src/lib/components/apps/components/layout/AppDivider.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppDivider.svelte @@ -1,5 +1,5 @@ {#each Object.keys(components['drawercomponent'].initialData.configuration) as key (key)} @@ -162,6 +162,7 @@ }} fullScreen={$mode !== 'dnd'} > + - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import { initConfig, initOutput } from '../../editor/appUtils' import SubGridEditor from '../../editor/SubGridEditor.svelte' import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types' @@ -37,12 +37,12 @@ getContext('AppViewerContext') let page = $state(0) - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect.pre(() => { render && !everRender && (everRender = true) }) - const outputs = initOutput($worldStore, id, { + const outputs = initOutput($worldStore, untrack(() => id), { result: undefined, loading: false, inputs: {}, @@ -50,7 +50,7 @@ }) let resolvedConfig = $state( - initConfig(components['listcomponent'].initialData.configuration, configuration) + initConfig(components['listcomponent'].initialData.configuration, untrack(() => configuration)) ) function onFocus() { @@ -60,7 +60,7 @@ } } - let css = $state(initCss($app.css?.listcomponent, customCss)) + let css = $state(initCss($app.css?.listcomponent, untrack(() => customCss))) let result: any[] | undefined = $state(undefined) let isCard = $derived(resolvedConfig.width?.selected == 'card') diff --git a/frontend/src/lib/components/apps/components/layout/AppModal.svelte b/frontend/src/lib/components/apps/components/layout/AppModal.svelte index 6232b667fd..9508303630 100644 --- a/frontend/src/lib/components/apps/components/layout/AppModal.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppModal.svelte @@ -1,7 +1,7 @@ diff --git a/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte b/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte index 7572c8c0fe..5a955a8ce6 100644 --- a/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppJsonEditor.svelte @@ -10,12 +10,12 @@ import { createEventDispatcher } from 'svelte' import { Globe, Loader2, Save } from 'lucide-svelte' - let jsonViewerDrawer: Drawer + let jsonViewerDrawer: Drawer | undefined = $state() - let code: string = '' + let code: string = $state('') let path: string = '' - let useDraft: boolean = false - let loading = true + let useDraft: boolean = $state(false) + let loading = $state(true) const dispatch = createEventDispatcher() let app: any | undefined = undefined @@ -73,7 +73,7 @@ - jsonViewerDrawer.toggleDrawer()}> + jsonViewerDrawer?.toggleDrawer()}> {#if useDraft} +Draft diff --git a/frontend/src/lib/components/apps/editor/AppPreview.svelte b/frontend/src/lib/components/apps/editor/AppPreview.svelte index 02114e1210..67c7ef4313 100644 --- a/frontend/src/lib/components/apps/editor/AppPreview.svelte +++ b/frontend/src/lib/components/apps/editor/AppPreview.svelte @@ -59,9 +59,9 @@ gotoFn = (path: string, opt?: Record) => window.history.pushState(null, '', path) }: Props = $props() - migrateApp(app) + migrateApp(untrack(() => app)) - const appStore = writable(app) + const appStore = writable(untrack(() => app)) const selectedComponent = writable(undefined) const mode = writable('preview') @@ -74,11 +74,11 @@ const allIdsInPath = writable([]) let ncontext: any = { - ...context, - workspace, + ...untrack(() => context), + workspace: untrack(() => workspace), mode: 'viewer', - summary: summary, - author: policy.on_behalf_of_email + summary: untrack(() => summary), + author: untrack(() => policy).on_behalf_of_email } function resizeWindow() { @@ -90,7 +90,7 @@ const parentWidth = writable(0) let previousDarkMode = document.documentElement.classList.contains('dark') - const darkMode: Writable = writable(app?.darkMode ?? previousDarkMode) + const darkMode: Writable = writable(untrack(() => app)?.darkMode ?? previousDarkMode) onDestroy(() => { setTheme(previousDarkMode) @@ -132,7 +132,7 @@ }) } - let writablePath = writable(appPath) + let writablePath = writable(untrack(() => appPath)) function onPathChange() { writablePath.set(appPath) @@ -146,21 +146,21 @@ runnableInitialized: {} }), app: appStore, - summary: writable(summary), + summary: writable(untrack(() => summary)), selectedComponent, bgRuns: writable([]), mode, connectingInput, - breakpoint, + breakpoint: untrack(() => breakpoint), runnableComponents: writable({}), appPath: writablePath, - workspace, + workspace: untrack(() => workspace), onchange: undefined, - isEditor, + isEditor: untrack(() => isEditor), jobs: parentContext?.jobs ?? writable([]), jobsById: parentContext?.jobsById ?? writable({}), staticExporter: writable({}), - noBackend, + noBackend: untrack(() => noBackend), errorByComponent: writable({}), openDebugRun: writable(undefined), focusedGrid: writable(undefined), @@ -174,9 +174,9 @@ cssEditorOpen: writable(false), previewTheme: writable(undefined), debuggingComponents: writable({}), - replaceStateFn, - gotoFn, - policy, + replaceStateFn: untrack(() => replaceStateFn), + gotoFn: untrack(() => gotoFn), + policy: untrack(() => policy), recomputeAllContext: writable({ loading: false, componentNumber: 0, @@ -319,6 +319,7 @@ {#snippet children({ dataItem })} + ($selectedComponent = [dataItem.id])} diff --git a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte index e717205670..28d8e5912a 100644 --- a/frontend/src/lib/components/apps/editor/ComponentHeader.svelte +++ b/frontend/src/lib/components/apps/editor/ComponentHeader.svelte @@ -297,7 +297,7 @@ 'text-red-500 px-1 text-2xs py-0.5 font-bold w-fit absolute border border-red-500 -bottom-1 shadow left-1/2 transform -translate-x-1/2 z-50 cursor-pointer' )} > - + {#snippet trigger()} {/snippet} diff --git a/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte b/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte index bf70dafd61..c5452be83e 100644 --- a/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte +++ b/frontend/src/lib/components/apps/editor/DecisionTreeDebug.svelte @@ -4,7 +4,7 @@ const bubble = createBubbler() import Dropdown from '$lib/components/DropdownV2.svelte' import { classNames } from '$lib/utils' - import { createEventDispatcher, getContext } from 'svelte' + import { createEventDispatcher, getContext, untrack } from 'svelte' import type { AppViewerContext } from '../types' import type { DecisionTreeNode } from './component' import { isDebugging } from './settingsPanel/decisionTree/utils' @@ -27,7 +27,7 @@ getContext('AppViewerContext') const dispatch = createEventDispatcher() - let currentNodeId: string = $state($worldStore.outputsById[id]?.currentNodeId?.peak() ?? 'a') + let currentNodeId: string = $state($worldStore.outputsById[untrack(() => id)]?.currentNodeId?.peak() ?? 'a') function subscribeToCurrentNode(id: string) { return $worldStore.outputsById[id]?.currentNodeId?.subscribe( @@ -41,7 +41,7 @@ ) } - let subscription = subscribeToCurrentNode(id) + let subscription = subscribeToCurrentNode(untrack(() => id)) function onDebugNode(debuggedNodeIndex: number | undefined) { if (debuggedNodeIndex === undefined) { @@ -63,7 +63,7 @@ }) let renderCount: number = $state(0) - let lastNodes: DecisionTreeNode[] = nodes + let lastNodes: DecisionTreeNode[] = untrack(() => nodes) function onNodesChange(newNodes: DecisionTreeNode[]) { if (JSON.stringify(newNodes) !== JSON.stringify(lastNodes)) { diff --git a/frontend/src/lib/components/apps/editor/GridEditor.svelte b/frontend/src/lib/components/apps/editor/GridEditor.svelte index d412bc1c56..d787564c0c 100644 --- a/frontend/src/lib/components/apps/editor/GridEditor.svelte +++ b/frontend/src/lib/components/apps/editor/GridEditor.svelte @@ -184,6 +184,7 @@ + rowHeight) let containerHeight = $derived(getContainerHeight(items, yPerPx, getComputedCols)) @@ -71,7 +71,7 @@ yPerPx, width: containerWidth }) - }, throttleUpdate) + }, untrack(() => throttleUpdate)) onMount(() => { setTimeout(() => { diff --git a/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte b/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte index 687262cf36..e00a128bf4 100644 --- a/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte +++ b/frontend/src/lib/components/apps/editor/RecomputeAllComponents.svelte @@ -1,4 +1,6 @@ (isActive = x)) - let everVisible = $state(visible) + let everVisible = $state(untrack(() => visible)) $effect.pre(() => { visible && !everVisible && (everVisible = true) @@ -199,6 +199,7 @@ {#if everVisible || $app.eagerRendering} + - import { getContext } from 'svelte' + import { getContext, untrack } from 'svelte' import ComponentInner from './ComponentInner.svelte' import ComponentRendered from './ComponentRendered.svelte' import type { AppComponent } from './components' @@ -25,7 +25,7 @@ overlapped = undefined, componentDraggedId = undefined }: Props = $props() - let everRender = $state(render) + let everRender = $state(untrack(() => render)) $effect(() => { render && !everRender && (everRender = true) diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte index c50b0ad656..2971a52654 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CssHelperPanel.svelte @@ -76,7 +76,7 @@ entries.sort((a, b) => (b.order ?? 0) - (a.order ?? 0) + a.name.localeCompare(b.name)) - let search = '' + let search = $state('') @@ -98,12 +98,15 @@ } }} > - - - - {name} - - + {#snippet titleSlot()} + {@const SvelteComponent = icon} + + + + {name} + + + {/snippet} {#if description} {description} {/if} diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte index 7460c30de9..3f65904c77 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/CustomComponentsList.svelte @@ -15,9 +15,9 @@ let customcomponents: Array<{ name: string path: string - }> = [] + }> = $state([]) - let loading: boolean = false + let loading: boolean = $state(false) async function getCustomComponents() { loading = true @@ -44,7 +44,7 @@ } }, name: nameField, - js: await files[0].text() + js: await files?.[0]?.text?.() } } }) @@ -61,10 +61,10 @@ nameField = '' } - let nameField: string = '' - let reactVersion: string = '18.2.0' - let files: FileList - let useReact = true + let nameField: string = $state('') + let reactVersion: string = $state('18.2.0') + let files: FileList | undefined = $state() + let useReact = $state(true) getCustomComponents() diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte index 6263bc8026..f4d8c40f72 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/NameEditor.svelte @@ -2,7 +2,7 @@ import Button from '$lib/components/common/button/Button.svelte' import Popover from '$lib/components/meltComponents/Popover.svelte' import { Pen } from 'lucide-svelte' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' interface Props { kind: string @@ -14,7 +14,7 @@ let { kind, row }: Props = $props() - let editedName = $state(row.name) + let editedName = $state(untrack(() => row).name) const dispatch = createEventDispatcher() function onkeydown(e) { diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte index cf5bda33c7..676c59c12d 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleMenu.svelte @@ -30,7 +30,7 @@ componentProperty = undefined }: Props = $props() const { app } = getContext('AppViewerContext') - const styleStore = createStyleStore(properties) + const styleStore = createStyleStore(untrack(() => properties)) setContext(STYLE_STORE_KEY, styleStore) let multiValues: Record = $state(initiateMultiValues()) @@ -210,12 +210,11 @@ toggleClasses=" !rounded-b-none !py-0 {isOpen[prefix] ? '!bg-surface-secondary hover:!bg-surface-hover' : ''}" > - - + {#snippet titleSlot()} {group} - + {/snippet} {#each property[group] as p} {@const { diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte index b4efdb87d4..54d9da3a33 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte +++ b/frontend/src/lib/components/apps/editor/componentsPanel/QuickStyleProperty.svelte @@ -1,5 +1,5 @@ diff --git a/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte b/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte index 579b769801..3c1a63ad81 100644 --- a/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte +++ b/frontend/src/lib/components/apps/editor/contextPanel/ComponentOutput.svelte @@ -1,6 +1,6 @@ diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte index 9b9d1f3563..992c52de83 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ComponentControl.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte index 6fb7b7be9b..be54285d84 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/ContextVariables.svelte @@ -1,7 +1,7 @@ - - - - - + {#snippet selectedTitle()} + + + + + {/snippet} {/if} diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte index af6f20e510..23419e51be 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte @@ -6,7 +6,7 @@ import type { InlineScript, Runnable, StaticAppInput } from '$lib/components/apps/inputType' import WorkspaceScriptList from './WorkspaceScriptList.svelte' import WorkspaceFlowList from './WorkspaceFlowList.svelte' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' import type { Schema } from '$lib/common' import { schemaToInputsSpec } from '$lib/components/apps/utils' import { defaultIfEmptyString, emptySchema } from '$lib/utils' @@ -34,7 +34,7 @@ // const { app, workspace } = getContext('AppViewerContext') let tab: TabType = $state( - onlyFlow + untrack(() => onlyFlow) ? 'workspaceflows' : unusedInlineScripts?.length > 0 ? 'inlinescripts' diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte index 877c48bf35..915e66e4db 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/lib/components/apps/svelte-grid/Grid.svelte b/frontend/src/lib/components/apps/svelte-grid/Grid.svelte index 4ffb2414ee..fd61edce4f 100644 --- a/frontend/src/lib/components/apps/svelte-grid/Grid.svelte +++ b/frontend/src/lib/components/apps/svelte-grid/Grid.svelte @@ -16,7 +16,7 @@ import { getContainerHeight } from './utils/container' import { moveItem, getItemById, specifyUndefinedColumns } from './utils/item' - import { onMount, getContext } from 'svelte' + import { onMount, getContext, untrack } from 'svelte' import { getColumn, throttle } from './utils/other' import MoveResize from './MoveResize.svelte' import type { FilledItem } from './types' @@ -97,7 +97,7 @@ let container = $state() let xPerPx = $state(0) - let yPerPx = rowHeight + let yPerPx = untrack(() => rowHeight) const onResizeThrottled = throttle(() => { if (!getComputedCols) return @@ -108,7 +108,7 @@ yPerPx, width: containerWidth }) - }, throttleUpdate) + }, untrack(() => throttleUpdate)) let mounted = $state(false) @@ -261,7 +261,7 @@ } } - const throttleMatrix = throttle(updateMatrix, throttleResize) + const throttleMatrix = throttle(updateMatrix, untrack(() => throttleResize)) //let hiddenComponents = writable({}) diff --git a/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte b/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte index 033a1a016c..d138023eed 100644 --- a/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte +++ b/frontend/src/lib/components/apps/svelte-grid/MoveResize.svelte @@ -1,5 +1,5 @@ @@ -41,29 +42,33 @@ {/if} {#if (asset.kind === 'resource' && resourceDataCacheValue === undefined) || ducklakeNotFound || datatableNotFound} - - - - - Not found - {#if ducklakeNotFound} - - Go to Ducklake settings - - {:else if datatableNotFound} - - Go to Data Table settings - - {:else if asset.kind === 'resource' && resourceDataCacheValue === undefined} - Go to Resources - {/if} - + {#snippet trigger()} + + + + {/snippet} + {#snippet content()} + + Not found + {#if ducklakeNotFound} + + Go to Ducklake settings + + {:else if datatableNotFound} + + Go to Data Table settings + + {:else if asset.kind === 'resource' && resourceDataCacheValue === undefined} + Go to Resources + {/if} + + {/snippet} {:else if assetCanBeExplored(asset, { resource_type: resourceDataCacheValue })} {@render badge()} - - {accessType2} access to column "{columnName}" - + {#snippet text()} + + {accessType2} access to column "{columnName}" + + {/snippet} {/if} {/each} diff --git a/frontend/src/lib/components/assets/AssetsDropdownButton.svelte b/frontend/src/lib/components/assets/AssetsDropdownButton.svelte index 5c530cf606..351ee68331 100644 --- a/frontend/src/lib/components/assets/AssetsDropdownButton.svelte +++ b/frontend/src/lib/components/assets/AssetsDropdownButton.svelte @@ -102,7 +102,7 @@ bind:isOpen escapeBehavior="ignore" > - + {#snippet trigger()} - - + {/snippet} + {#snippet content()} {#each assets as asset} {@const ducklakeNotFound = @@ -144,7 +144,7 @@ contentClasses="py-2 px-4 flex flex-col gap-2" disablePopup={!!asset.access_type} > - + {#snippet trigger()} {formatAssetAccessType(getAccessType(asset)) ?? '?'} - - + {/snippet} + {#snippet content()} {#if !asset.access_type} Could not infer automatically @@ -180,14 +180,14 @@ {/if} - + {/snippet} {asset.path} - + {#snippet text()} {asset.path} - + {/snippet} {liSubtitle?.(asset) ?? @@ -216,7 +216,7 @@ {/each} - + {/snippet} diff --git a/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte b/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte index 177032341b..16effb700a 100644 --- a/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte +++ b/frontend/src/lib/components/assets/AssetsUsageDrawer.svelte @@ -71,11 +71,13 @@ {text} - - {#if tooltip} - {tooltip} - {/if} - + {#snippet text()} + + {#if tooltip} + {tooltip} + {/if} + + {/snippet} {/if} {/snippet} diff --git a/frontend/src/lib/components/assets/VolumesDrawer.svelte b/frontend/src/lib/components/assets/VolumesDrawer.svelte index bd00dd0dba..06d4f9529a 100644 --- a/frontend/src/lib/components/assets/VolumesDrawer.svelte +++ b/frontend/src/lib/components/assets/VolumesDrawer.svelte @@ -52,10 +52,7 @@ refreshKey++ } - function canReadVolume( - createdBy: string, - extraPerms?: { [key: string]: unknown } - ): boolean { + function canReadVolume(createdBy: string, extraPerms?: { [key: string]: unknown }): boolean { if ($userStore?.is_admin) return true const username = $userStore?.username if (username === createdBy || `u/${username}` === createdBy) return true @@ -67,10 +64,7 @@ return pgroups.some((g) => g in perms) } - function canWriteVolume( - createdBy: string, - extraPerms?: { [key: string]: unknown } - ): boolean { + function canWriteVolume(createdBy: string, extraPerms?: { [key: string]: unknown }): boolean { if ($userStore?.is_admin) return true const username = $userStore?.username if (username === createdBy || `u/${username}` === createdBy) return true @@ -83,10 +77,7 @@ (open = false)}> (open = false)}> {#snippet actions()} - + {#snippet trigger()} New volume - Volumes are limited to 20 per workspace and 50 MB per file. Upgrade to Enterprise - Edition to remove these limits. + Volumes are limited to 20 per workspace and 50 MB per file. Upgrade to Enterprise Edition + to remove these limits. {/if} @@ -133,7 +124,8 @@ {:else if !volumes.current?.length} - No volumes yet. Create one above or they are auto-created when a job declares a volume annotation. + No volumes yet. Create one above or they are auto-created when a job declares a volume + annotation. {:else} @@ -151,7 +143,8 @@ /> - {vol.file_count} {vol.file_count === 1 ? 'file' : 'files'} + {vol.file_count} + {vol.file_count === 1 ? 'file' : 'files'} · {displaySize(vol.size_bytes) ?? '0 B'} · owner: {vol.created_by.replace(/^u\//, '')} @@ -167,8 +160,7 @@ iconOnly unifiedSize="sm" endIcon={{ icon: Shield }} - on:click={() => - shareModal?.openDrawer(vol.name, 'volume', true)} + on:click={() => shareModal?.openDrawer(vol.name, 'volume', true)} /> {/if} {#if onExplore && readable} diff --git a/frontend/src/lib/components/chartjs-wrappers/Chart.svelte b/frontend/src/lib/components/chartjs-wrappers/Chart.svelte index 9fdacd47de..66739a7859 100644 --- a/frontend/src/lib/components/chartjs-wrappers/Chart.svelte +++ b/frontend/src/lib/components/chartjs-wrappers/Chart.svelte @@ -27,8 +27,8 @@ untrack(() => { chart = new Chart(canvasElem, { type, - data, - options + data: $state.snapshot(data) as typeof data, + options: $state.snapshot(options) as typeof options }) }) return () => { @@ -37,10 +37,10 @@ }) $effect(() => { - chart + data untrack(() => { if (chart) { - chart.data = data + chart.data = $state.snapshot(data) as typeof data chart.update() } }) diff --git a/frontend/src/lib/components/common/FileProgressBar.svelte b/frontend/src/lib/components/common/FileProgressBar.svelte index d339d9477f..5cb864981b 100644 --- a/frontend/src/lib/components/common/FileProgressBar.svelte +++ b/frontend/src/lib/components/common/FileProgressBar.svelte @@ -1,23 +1,38 @@ {#key color} {#if ended} - + {@render children?.()} {:else} - export let notificationCount = 0 - export let notificationLimit: number | undefined = undefined + interface Props { + notificationCount?: number; + notificationLimit?: number | undefined; + } + + let { notificationCount = 0, notificationLimit = undefined }: Props = $props(); {#if notificationCount > 0} diff --git a/frontend/src/lib/components/common/button/AnimatedButton.svelte b/frontend/src/lib/components/common/button/AnimatedButton.svelte index 7248b891dc..3ceb0ebd4c 100644 --- a/frontend/src/lib/components/common/button/AnimatedButton.svelte +++ b/frontend/src/lib/components/common/button/AnimatedButton.svelte @@ -1,12 +1,26 @@ {#if animate} @@ -19,10 +33,10 @@ {ringColor} {darkMode} > - + {@render children?.()} {:else} - + {@render children?.()} {/if} diff --git a/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte b/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte index 7396b5314b..9ba46928a0 100644 --- a/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte +++ b/frontend/src/lib/components/common/button/AnimatedButtonInner.svelte @@ -1,27 +1,41 @@ @@ -33,7 +47,7 @@ bind:clientWidth bind:clientHeight > - + {@render children?.()}
No permission changes recorded yet
{#if typeof label !== 'string'} diff --git a/frontend/src/lib/components/Range.svelte b/frontend/src/lib/components/Range.svelte index 0e92ac72de..72129aada2 100644 --- a/frontend/src/lib/components/Range.svelte +++ b/frontend/src/lib/components/Range.svelte @@ -1,29 +1,47 @@
docker compose up -d