Files
windmill/frontend/src/lib/components/flows/content/FlowModuleHeader.svelte
T
2024-08-02 13:47:28 +02:00

198 lines
6.0 KiB
Svelte

<script lang="ts">
import Button from '$lib/components/common/button/Button.svelte'
import { WorkerService, type FlowModule } from '$lib/gen'
import { createEventDispatcher, getContext } from 'svelte'
import {
Bed,
Database,
Gauge,
GitFork,
Pen,
PhoneIncoming,
Repeat,
Save,
Square,
Voicemail
} from 'lucide-svelte'
import Popover from '../../Popover.svelte'
import type { FlowEditorContext } from '../types'
import { sendUserToast } from '$lib/utils'
import { workerTags } from '$lib/stores'
import { getLatestHashForScript } from '$lib/scripts'
import type { WhitelabelCustomUi } from '$lib/components/custom_ui'
export let module: FlowModule
const { scriptEditorDrawer, flowStore, selectedId } =
getContext<FlowEditorContext>('FlowEditorContext')
const dispatch = createEventDispatcher()
let customUi: undefined | WhitelabelCustomUi = getContext('customUi')
loadWorkerGroups()
async function loadWorkerGroups() {
if (!$workerTags) {
$workerTags = await WorkerService.getCustomTags()
}
}
$: moduleRetry = module.retry?.constant || module.retry?.exponential
</script>
<div class="flex flex-row space-x-1">
{#if module.value.type === 'script' || module.value.type === 'rawscript' || module.value.type == 'flow'}
{#if moduleRetry}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleRetry')}
>
<Repeat size={14} />
<svelte:fragment slot="text">Retries</svelte:fragment>
</Popover>
{/if}
{#if module?.value?.['concurrent_limit'] != undefined}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleConcurrency')}
>
<Gauge size={14} />
<svelte:fragment slot="text">Concurrency Limits</svelte:fragment>
</Popover>
{/if}
{#if module.cache_ttl != undefined}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleCache')}
>
<Database size={14} />
<svelte:fragment slot="text">Cache</svelte:fragment>
</Popover>
{/if}
{#if module.stop_after_if}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleStopAfterIf')}
>
<Square size={14} />
<svelte:fragment slot="text">Early stop/break</svelte:fragment>
</Popover>
{/if}
{#if module.suspend}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleSuspend')}
>
<PhoneIncoming size={14} />
<svelte:fragment slot="text">Suspend</svelte:fragment>
</Popover>
{/if}
{#if module.sleep}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleSleep')}
>
<Bed size={14} />
<svelte:fragment slot="text">Sleep</svelte:fragment>
</Popover>
{/if}
{#if module.mock?.enabled}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
on:click={() => dispatch('toggleMock')}
>
<Voicemail size={14} />
<svelte:fragment slot="text">Mock</svelte:fragment>
</Popover>
{/if}
{/if}
{#if module.value.type === 'script'}
<div class="w-2" />
{#if !module.value.path.startsWith('hub/')}
<Button
size="xs"
color="light"
on:click={async () => {
if (module.value.type == 'script') {
const hash = module.value.hash ?? (await getLatestHashForScript(module.value.path))
$scriptEditorDrawer?.openDrawer(hash, () => {
dispatch('reload')
sendUserToast('Script has been updated')
})
}
}}
startIcon={{ icon: Pen }}
iconOnly={false}
disabled={module.value.hash != undefined}
>
Edit {#if module.value.hash != undefined} (locked hash){/if}
</Button>
{/if}
{#if customUi?.scriptFork != false}
<Button
size="xs"
color="light"
on:click={() => dispatch('fork')}
startIcon={{ icon: GitFork }}
iconOnly={false}
>
Fork
</Button>
{/if}
{/if}
<div class="px-0.5" />
{#if module.value.type === 'rawscript'}
{#if $workerTags}
{#if $workerTags?.length > 0}
<div class="w-40">
{#if $flowStore.tag == undefined}
<select
placeholder="Tag"
bind:value={module.value.tag}
on:change={(e) => {
if (module.value.type === 'rawscript') {
if (module.value.tag == '') {
module.value.tag = undefined
}
}
}}
>
{#if module.value.tag}
<option value="">reset to default</option>
{:else}
<option value="" disabled selected>Tag</option>
{/if}
{#each $workerTags ?? [] as tag (tag)}
<option value={tag}>{tag}</option>
{/each}
</select>
{:else}
<button
title="Worker Group is defined at the flow level"
class="w-full text-left items-center font-normal p-1 border text-xs rounded"
on:click={() => ($selectedId = 'settings-worker-group')}
>
Flow's WG: {$flowStore.tag}
</button>
{/if}
</div>
{/if}
{/if}
<Button
size="xs"
color="light"
startIcon={{ icon: Save }}
on:click={() => dispatch('createScriptFromInlineScript')}
iconOnly={false}
>
Save to workspace
</Button>
{/if}
</div>