{#if appPath == ''} closeDraftDrawer()}> Choose a path to save the initial draft of the app.

Summary

{ if (appPath == '' && $summary?.length > 0 && !dirtyPath) { path?.setName( $summary .toLowerCase() .replace(/[^a-z0-9_]/g, '_') .replace(/-+/g, '_') .replace(/^-|-$/g, '') ) } }} />
{/if} closeSaveDrawer()}> {#if !onLatest} By deploying, you may overwrite changes made by other users.
{/if} Summary
{ if (appPath == '' && $summary?.length > 0 && !dirtyPath) { path?.setName( $summary .toLowerCase() .replace(/[^a-z0-9_]/g, '_') .replace(/-+/g, '_') .replace(/^-|-$/g, '') ) } }} />
Deployment message
Path
{#if appPath == ''} Save this app once before you can publish it {:else} A viewer of the app will execute the runnables of the app on behalf of the publisher (you) It ensures that all required resources/runnable visible for publisher but not for viewer at time of creating the app would prevent the execution of the app. To guarantee tight security, a policy is computed at time of deployment of the app which only allow the scripts/flows referred to in the app to be called on behalf of. Furthermore, static parameters are not overridable. Hence, users will only be able to use the app as intended by the publisher without risk for leaking resources not used in the app.

Secret public URL

{ policy.execution_mode = e.detail ? 'anonymous' : 'publisher' setPublishState() }} />
Secret public url: {#if secretUrl} {@const url = `${$page.url.hostname}/public/${$workspaceStore}/${secretUrl}`} {@const href = $page.url.protocol + '//' + url} { e.preventDefault() copyToClipboard(href) }} {href} class="whitespace-nowrap text-ellipsis overflow-hidden mr-1 inline-flex gap-2" > {url} {:else} {/if}
You may share this url directly or embed it using an iframe (if not requiring login)
You will still need to deploy the app to make visible the latest changes {/if} (inputsDrawerOpen = false)}> (historyBrowserDrawerOpen = false)}> (debugAppDrawerOpen = false)}> { $jobsDrawerOpen = false }} tooltip="Look at latests runs to spot potential bugs." documentationLink="https://www.windmill.dev/docs/apps/app_debugging" >
{#if $jobs.length > 0}
{#each $jobs ?? [] as id} {@const selectedJob = $jobsById[id]} {#if selectedJob}
{ selectedJobId = id rightColumnSelect = 'detail' }} > {truncateRev(selectedJob.job, 20)} {selectedJob.component}
{/if} {/each}
{:else}
No items
{/if}
Timeline Details
{#if rightColumnSelect == 'timeline'}
{:else if rightColumnSelect == 'detail'}
{#if selectedJobId} {#if selectedJobId?.includes('Frontend')} {@const jobResult = $jobsById[selectedJobId]} {#if jobResult?.error !== undefined}
{:else if jobResult !== undefined}
{:else} {/if} {:else}
{#if job?.['running']}
{/if} {#if job?.args}
{/if} {#if job?.raw_code}
{/if} {#if job?.job_kind !== 'flow' && job?.job_kind !== 'flowpreview'} {@const jobResult = $jobsById[selectedJobId]} {#if job != undefined && 'result' in job && job.result != undefined}
{:else if testIsLoading}
{:else if job != undefined && 'result' in job && job?.['result'] == undefined}
Result is undefined
{:else}
{/if}
{#if jobResult?.transformer}
Transformer results
{#if job != undefined && 'result' in job && job.result != undefined}
{:else if testIsLoading}
{:else if job != undefined && 'result' in job && job?.['result'] == undefined}
Result is undefined
{:else}
{/if}
{/if}
{:else}
{ job = detail }} />
{/if}
{/if} {:else}
Select a job to see its details
{/if}
{/if}
{#if hasErrors} {/if}
{ $app = undo(history, $app) }} on:redo={() => { $app = redo(history) }} /> {#if $app} {/if}
{#if $enterpriseLicense && appPath != ''} {/if}
{#each moreItems as item}
{item.displayName}
{/each}