fix: public url in app menu

This commit is contained in:
Ruben Fiszel
2025-06-28 19:41:12 +02:00
parent bb110985e2
commit ca368aba7a
@@ -28,7 +28,9 @@
Sun,
Moon,
SunMoon,
Zap
Zap,
Globe,
AlertTriangle
} from 'lucide-svelte'
import { createEventDispatcher, getContext, untrack } from 'svelte'
import {
@@ -773,7 +775,13 @@
let dirtyPath = $state(false)
let path: Path | undefined = $state(undefined)
let moreItems = [
let secretUrlHref = $derived(
secretUrl
? `${window.location.origin}${base}/public/${$workspaceStore}/${secretUrl}`
: undefined
)
let moreItems = $derived([
{
displayName: 'Deployment history',
icon: History,
@@ -789,6 +797,12 @@
appExport?.open($app)
}
},
{
displayName: 'Public URL',
icon: Globe,
disabled: !secretUrlHref,
href: secretUrlHref
},
// {
// displayName: 'Publish to Hub',
// icon: faGlobe,
@@ -797,13 +811,7 @@
// window.open(url.toString(), '_blank')
// }
// },
{
displayName: 'Hub compatible JSON',
icon: FileUp,
action: () => {
appExport?.open(toStatic($app, $staticExporter, $summary).app)
}
},
{
displayName: 'App inputs',
icon: FormInput,
@@ -860,8 +868,15 @@
action: () => {
lazyDrawerOpen = true
}
},
{
displayName: 'Hub export',
icon: FileUp,
action: () => {
appExport?.open(toStatic($app, $staticExporter, $summary).app)
}
}
]
])
let appEditorTutorial: AppEditorTutorial | undefined = $state(undefined)
@@ -1167,29 +1182,24 @@
</div>
{/snippet}
<div class="py-2"></div>
{#if $appPath == ''}
<Alert title="Require saving" type="error">
Save this app once before you can publish it
</Alert>
{:else}
<Alert title="App executed on behalf of you">
A viewer of the app will execute the runnables of the app on behalf of the publisher (you)
<Tooltip>
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.
</Tooltip>
</Alert>
<Alert title="App executed on behalf of you">
A viewer of the app will execute the runnables of the app on behalf of the publisher (you)
<Tooltip>
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.
</Tooltip>
</Alert>
<div class="mt-10"></div>
<div class="mt-10"></div>
<h2>Public URL</h2>
<div class="mt-4"></div>
<h2>Public URL</h2>
<div class="flex gap-2 items-center">
<div class="my-6">
<div class="flex gap-2 items-center mb-2">
<Toggle
options={{
left: `Require login and read-access`,
@@ -1200,85 +1210,82 @@
policy.execution_mode = e.detail ? 'anonymous' : 'publisher'
setPublishState()
}}
disabled={$appPath == ''}
/>
</div>
<div class="my-6 box">
<div class="text-secondary">
<div>Public URL</div>
</div>
{#if secretUrl}
{@const href = `${window.location.origin}${base}/public/${$workspaceStore}/${secretUrl}`}
<ClipboardPanel content={href} size="md" />
{:else}<Loader2 class="animate-spin" />
{/if}
<div class="text-xs text-secondary mt-1">
Share this url directly or embed it using an iframe (if requiring login, top-level domain
of embedding app must be the same as the one of Windmill)
</div>
<div class="mt-4">
{#if !$enterpriseLicense}
<Alert title="EE Only" type="warning" size="xs">
Custom path is an enterprise only feature.
</Alert>
<div class="mb-2"></div>
{:else if !($userStore?.is_admin || $userStore?.is_super_admin)}
<Alert type="warning" title="Admin only" size="xs">
Custom path can only be set by workspace admins
</Alert>
<div class="mb-2"></div>
{/if}
<Toggle
on:change={({ detail }) => {
customPath = detail ? '' : undefined
if (customPath === undefined) {
customPathError = ''
}
}}
checked={customPath !== undefined}
options={{
right: 'Use a custom URL'
}}
disabled={!$enterpriseLicense || !($userStore?.is_admin || $userStore?.is_super_admin)}
/>
{#if customPath !== undefined}
<div class="text-secondary text-sm flex items-center gap-1 w-full justify-between">
<div>Custom path</div>
</div>
<input
disabled={!($userStore?.is_admin || $userStore?.is_super_admin)}
type="text"
autocomplete="off"
bind:value={customPath}
class={customPathError === ''
? ''
: 'border border-red-700 bg-red-100 border-opacity-30 focus:border-red-700 focus:border-opacity-30 focus-visible:ring-red-700 focus-visible:ring-opacity-25 focus-visible:border-red-700'}
oninput={() => {
dirtyCustomPath = true
}}
/>
<div class="text-secondary text-sm flex items-center gap-1 mt-2 w-full justify-between">
<div>Custom public URL</div>
</div>
<ClipboardPanel content={fullCustomUrl} size="md" />
<div class="text-red-600 dark:text-red-400 text-2xs mt-1.5"
>{dirtyCustomPath ? customPathError : ''}
</div>
{/if}
</div>
{#if $appPath == ''}
<ClipboardPanel content={`Save this app once to get the public secret URL`} size="md" />
{:else if secretUrlHref}
<ClipboardPanel content={secretUrlHref} size="md" />
{:else}<Loader2 class="animate-spin" />
{/if}
<div class="text-xs text-secondary mt-1">
Share this url directly or embed it using an iframe (if requiring login, top-level domain of
embedding app must be the same as the one of Windmill)
</div>
<Alert type="info" title="Only latest deployed app is publicly available">
You will still need to deploy the app to make visible the latest changes
</Alert>
<a
href="https://www.windmill.dev/docs/advanced/external_auth_with_jwt#embed-public-apps-using-your-own-authentification"
class="mt-4 text-2xs">Embed this app in your own product to be used by your own users</a
>
{/if}
<div class="mt-4">
{#if !($userStore?.is_admin || $userStore?.is_super_admin)}
<Alert type="warning" title="Admin only" size="xs">
Custom path can only be set by workspace admins
</Alert>
<div class="mb-2"></div>
{/if}
{#if !$enterpriseLicense}
<div class="flex text-xs items-center gap-1 text-yellow-500 whitespace-nowrap mb-2">
<AlertTriangle size={16} />
EE only <Tooltip>Enterprise Edition only feature</Tooltip>
</div>
{/if}
<Toggle
on:change={({ detail }) => {
customPath = detail ? '' : undefined
if (customPath === undefined) {
customPathError = ''
}
}}
checked={customPath !== undefined}
options={{
right: 'Use a custom URL'
}}
disabled={!$enterpriseLicense || !($userStore?.is_admin || $userStore?.is_super_admin)}
/>
{#if customPath !== undefined}
<div class="text-secondary text-sm flex items-center gap-1 w-full justify-between">
<div>Custom path</div>
</div>
<input
disabled={!($userStore?.is_admin || $userStore?.is_super_admin)}
type="text"
autocomplete="off"
bind:value={customPath}
class={customPathError === ''
? ''
: 'border border-red-700 bg-red-100 border-opacity-30 focus:border-red-700 focus:border-opacity-30 focus-visible:ring-red-700 focus-visible:ring-opacity-25 focus-visible:border-red-700'}
oninput={() => {
dirtyCustomPath = true
}}
/>
<div class="text-secondary text-sm flex items-center gap-1 mt-2 w-full justify-between">
<div>Custom public URL</div>
</div>
<ClipboardPanel content={fullCustomUrl} size="md" />
<div class="text-red-600 dark:text-red-400 text-2xs mt-1.5"
>{dirtyCustomPath ? customPathError : ''}
</div>
{/if}
</div>
</div>
<Alert type="info" title="Only latest deployed app is publicly available">
You will still need to deploy the app to make visible the latest changes
</Alert>
<a
href="https://www.windmill.dev/docs/advanced/external_auth_with_jwt#embed-public-apps-using-your-own-authentification"
class="mt-4 text-2xs">Embed this app in your own product to be used by your own users</a
>
</DrawerContent>
</Drawer>