diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte index 103100be69..ca43689495 100644 --- a/frontend/src/lib/components/FlowBuilder.svelte +++ b/frontend/src/lib/components/FlowBuilder.svelte @@ -82,6 +82,7 @@ import type { FlowBuilderWhitelabelCustomUi } from './custom_ui' import FlowYamlEditor from './flows/header/FlowYamlEditor.svelte' import { type TriggerContext, type ScheduleTrigger } from './triggers' + import type { SavedAndModifiedValue } from './common/confirmationModal/unsavedTypes' export let initialPath: string = '' export let pathStoreInit: string | undefined = undefined @@ -112,6 +113,12 @@ $: setContext('customUi', customUi) + export function getInitialAndModifiedValues(): SavedAndModifiedValue { + return { + savedValue: savedFlow, + modifiedValue: $flowStore + } + } let onLatest = true async function compareVersions() { if (version === undefined) { diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 7722cce461..048d5cfe0d 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -76,6 +76,7 @@ PYTHON_PREPROCESSOR_MODULE_CODE } from '$lib/script_helpers' import CaptureTable from './triggers/CaptureTable.svelte' + import type { SavedAndModifiedValue } from './common/confirmationModal/unsavedTypes' export let script: NewScript export let fullyLoaded: boolean = true @@ -94,6 +95,13 @@ export let customUi: ScriptBuilderWhitelabelCustomUi = {} export let savedPrimarySchedule: ScheduleTrigger | undefined = undefined + export function getInitialAndModifiedValues(): SavedAndModifiedValue { + return { + savedValue: savedScript, + modifiedValue: script + } + } + let deployedValue: Value | undefined = undefined // Value to diff against let deployedBy: string | undefined = undefined // Author let confirmCallback: () => void = () => {} // What happens when user clicks `override` in warning diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte index e9ae1d3f66..881810289a 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte @@ -949,14 +949,16 @@ ({ + savedValue: savedApp, + modifiedValue: { + summary: $summary, + value: $app, + path: newEditedPath || savedApp?.draft?.path || savedApp?.path, + policy, + custom_path: customPath + } + })} additionalExitAction={() => { setTheme(priorDarkMode) }} diff --git a/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte b/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte index e0161044a4..971cd6735d 100644 --- a/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte +++ b/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte @@ -10,13 +10,14 @@ replaceFalseWithUndefined, type Value } from '$lib/utils' - import { tick } from 'svelte' import { page } from '$app/stores' + import type { GetInitialAndModifiedValues } from './unsavedTypes' - export let savedValue: Value | undefined = undefined - export let modifiedValue: Value | undefined = undefined + export let getInitialAndModifiedValues: GetInitialAndModifiedValues = undefined export let diffDrawer: DiffDrawer | undefined = undefined export let additionalExitAction: () => void = () => {} + let savedValue: Value | undefined = undefined + let modifiedValue: Value | undefined = undefined let bypassBeforeNavigate = false let open = false @@ -25,6 +26,7 @@ beforeNavigate(async (newNavigationState) => { if ( !bypassBeforeNavigate && + getInitialAndModifiedValues && newNavigationState.to && newNavigationState.to.url != $page.url && newNavigationState.to.url.pathname !== newNavigationState.from?.url.pathname @@ -32,9 +34,9 @@ // console.log('going to', newNavigationState.to.url) goingTo = newNavigationState.to.url - if (newNavigationState.type != 'popstate') { - await tick() // make sure saved value is updated when clicking on save draft or deploy - } + const state = getInitialAndModifiedValues?.() + savedValue = state?.savedValue + modifiedValue = state?.modifiedValue async function openModal() { newNavigationState.cancel() diff --git a/frontend/src/lib/components/flows/content/ScriptEditorDrawer.svelte b/frontend/src/lib/components/flows/content/ScriptEditorDrawer.svelte index b696e0600b..fc436571d1 100644 --- a/frontend/src/lib/components/flows/content/ScriptEditorDrawer.svelte +++ b/frontend/src/lib/components/flows/content/ScriptEditorDrawer.svelte @@ -129,7 +129,6 @@ } - string) | undefined = undefined let flowBuilder: FlowBuilder | undefined = undefined - let savedFlow: - | (Flow & { - draft?: Flow | undefined - }) - | undefined = undefined + let getInitialAndModifiedValues: GetInitialAndModifiedValues | undefined = undefined @@ -169,9 +165,9 @@ {initialPath} {pathStoreInit} bind:getSelectedId + bind:getInitialAndModifiedValues bind:this={flowBuilder} newFlow - bind:savedFlow {initialArgs} {flowStore} {flowStateStore} @@ -179,5 +175,5 @@ {loading} {savedPrimarySchedule} > - + + diff --git a/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte index 1de2df3f31..b62077af94 100644 --- a/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte @@ -15,7 +15,7 @@ import UnsavedConfirmationModal from '$lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte' import type { ScheduleTrigger } from '$lib/components/triggers' - let version: undefined | number = undefined; + let version: undefined | number = undefined let nodraft = $page.url.searchParams.get('nodraft') const initialState = nodraft ? undefined : localStorage.getItem(`flow-${$page.params.path}`) let stateLoadedFromUrl = initialState != undefined ? decodeState(initialState) : undefined @@ -68,10 +68,12 @@ if (stateLoadedFromUrl != undefined && statePath == $page.params.path) { // Currently there is no way to get version of flow with flow. // So we have to request it here - version = (await FlowService.getFlowLatestVersion({ - workspace: $workspaceStore!, - path: statePath - })).id; + version = ( + await FlowService.getFlowLatestVersion({ + workspace: $workspaceStore!, + path: statePath + }) + ).id savedFlow = await FlowService.getFlowByPathWithDraft({ workspace: $workspaceStore!, @@ -113,10 +115,12 @@ } else { // Currently there is no way to get version of flow with flow. // So we have to request it here - version = (await FlowService.getFlowLatestVersion({ - workspace: $workspaceStore!, - path: $page.params.path - })).id; + version = ( + await FlowService.getFlowLatestVersion({ + workspace: $workspaceStore!, + path: $page.params.path + }) + ).id const flowWithDraft = await FlowService.getFlowByPathWithDraft({ workspace: $workspaceStore!, @@ -129,7 +133,7 @@ ...structuredClone(flowWithDraft.draft), path: flowWithDraft.draft.path ?? flowWithDraft.path // backward compatibility for old drafts missing path } - : undefined + : undefined } as Flow & { draft?: Flow } @@ -215,6 +219,7 @@ goto(`/flows/edit/${savedFlow.path}`) loadFlow() } + let getInitialAndModifiedValues: GetInitialAndModifiedValues | undefined = undefined @@ -246,6 +251,7 @@ {diffDrawer} {savedPrimarySchedule} bind:version + bind:getInitialAndModifiedValues > - + diff --git a/frontend/src/routes/(root)/(logged)/scripts/add/+page.svelte b/frontend/src/routes/(root)/(logged)/scripts/add/+page.svelte index c4c8de15bf..1def25b2d4 100644 --- a/frontend/src/routes/(root)/(logged)/scripts/add/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/scripts/add/+page.svelte @@ -10,6 +10,7 @@ import { replaceState } from '$app/navigation' import UnsavedConfirmationModal from '$lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte' import type { ScheduleTrigger } from '$lib/components/triggers' + import type { GetInitialAndModifiedValues } from '$lib/components/common/confirmationModal/unsavedTypes' // Default let schema: Schema = emptySchema() @@ -100,7 +101,8 @@ loadTemplate() } } - let savedScript: Script | undefined = undefined + + let getInitialAndModifiedValues: GetInitialAndModifiedValues = undefined replaceState(path, $page.state)} > - + diff --git a/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte index 2479985148..fbe85f83c0 100644 --- a/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte @@ -11,6 +11,7 @@ import DiffDrawer from '$lib/components/DiffDrawer.svelte' import UnsavedConfirmationModal from '$lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte' import type { ScheduleTrigger } from '$lib/components/triggers' + import type { GetInitialAndModifiedValues } from '$lib/components/common/confirmationModal/unsavedTypes' let initialState = window.location.hash != '' ? window.location.hash.slice(1) : undefined let initialArgs = {} @@ -194,6 +195,8 @@ goto(`/scripts/edit/${savedScript.path}`) loadScript() } + + let getInitialAndModifiedValues: GetInitialAndModifiedValues = undefined @@ -212,6 +215,7 @@ let newHash = e.detail goto(`/scripts/get/${newHash}?workspace=${$workspaceStore}`) }} + bind:getInitialAndModifiedValues on:saveInitial={(e) => { let path = e.detail goto(`/scripts/edit/${path}`) @@ -223,10 +227,7 @@ replaceStateFn={(path) => { replaceState(path, $page.state) }} - > + + {/if}