mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 16:02:14 +00:00
142 lines
3.6 KiB
Svelte
142 lines
3.6 KiB
Svelte
<script lang="ts">
|
|
import type { FlowEditorContext } from '../types'
|
|
import { getContext } from 'svelte'
|
|
import { deleteFlowStateById, emptyModule, idMutex } from '$lib/components/flows/flowStateUtils'
|
|
import { flowStateStore } from '../flowState'
|
|
import type { FlowModule } from '$lib/gen'
|
|
import FlowErrorHandlerItem from './FlowErrorHandlerItem.svelte'
|
|
import RemoveStepConfirmationModal from '../content/RemoveStepConfirmationModal.svelte'
|
|
import { emptyFlowModuleState, isEmptyFlowModule } from '../utils'
|
|
import MapItem from './MapItem.svelte'
|
|
import FlowSettingsItem from './FlowSettingsItem.svelte'
|
|
import FlowInputsItem from './FlowInputsItem.svelte'
|
|
import InsertModuleButton from './InsertModuleButton.svelte'
|
|
|
|
export let root: boolean = false
|
|
export let color: 'blue' | 'orange' | 'indigo' = 'blue'
|
|
export let modules: FlowModule[]
|
|
|
|
let indexToRemove: number | undefined = undefined
|
|
const { select } = getContext<FlowEditorContext>('FlowEditorContext')
|
|
|
|
async function insertNewModuleAtIndex(index: number): Promise<void> {
|
|
await idMutex.runExclusive(async () => {
|
|
const flowModule = emptyModule()
|
|
modules.splice(index, 0, flowModule)
|
|
modules = modules
|
|
$flowStateStore[flowModule.id] = emptyFlowModuleState()
|
|
select(flowModule.id)
|
|
})
|
|
}
|
|
|
|
function removeAtIndex(index: number): void {
|
|
select('settings')
|
|
const [removedModule] = modules.splice(index, 1)
|
|
modules = modules
|
|
|
|
const leaves = findLeaves(removedModule)
|
|
|
|
leaves.forEach((leafId: string) => deleteFlowStateById(leafId))
|
|
}
|
|
|
|
function findLeaves(flowModule: FlowModule): string[] {
|
|
const id = flowModule.id
|
|
|
|
if (flowModule.value.type === 'forloopflow') {
|
|
return [id, ...flowModule.value.modules.map((fm) => findLeaves(fm)).flat()]
|
|
}
|
|
|
|
if (flowModule.value.type === 'branchall') {
|
|
return [
|
|
id,
|
|
...flowModule.value.branches
|
|
.map((branch) => branch.modules.map((mod) => findLeaves(mod)).flat())
|
|
.flat()
|
|
]
|
|
}
|
|
|
|
if (flowModule.value.type === 'branchone') {
|
|
return [
|
|
id,
|
|
...flowModule.value.branches
|
|
.map((branch) => {
|
|
return branch.modules.map((mod) => findLeaves(mod)).flat()
|
|
})
|
|
.flat(),
|
|
...flowModule.value.default.map((mod) => findLeaves(mod)).flat()
|
|
]
|
|
}
|
|
|
|
return [id]
|
|
}
|
|
|
|
$: confirmationModalOpen = indexToRemove !== undefined
|
|
</script>
|
|
|
|
<div class="flex flex-col h-full">
|
|
{#if root}
|
|
<div class="flex-initial p-4 border-b">
|
|
<FlowSettingsItem />
|
|
</div>
|
|
{/if}
|
|
<ul class="w-full flex-auto relative overflow-y-auto overflow-x-hidden pl-2 pr-1 py-4">
|
|
{#if root}
|
|
<li>
|
|
<FlowInputsItem />
|
|
</li>
|
|
{/if}
|
|
|
|
{#each modules as mod, index (mod.id ?? index)}
|
|
<MapItem
|
|
{color}
|
|
{index}
|
|
bind:mod
|
|
on:delete={(event) => {
|
|
if (event.detail.detail.shiftKey || isEmptyFlowModule(mod)) {
|
|
removeAtIndex(index)
|
|
} else {
|
|
indexToRemove = index
|
|
}
|
|
}}
|
|
on:insert={() => {
|
|
insertNewModuleAtIndex(index)
|
|
}}
|
|
/>
|
|
{/each}
|
|
|
|
<InsertModuleButton on:click={() => insertNewModuleAtIndex(modules.length)} />
|
|
</ul>
|
|
{#if root}
|
|
<div class="flex-none p-4 border-t">
|
|
<FlowErrorHandlerItem />
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<RemoveStepConfirmationModal
|
|
bind:open={confirmationModalOpen}
|
|
on:canceled={() => {
|
|
indexToRemove = undefined
|
|
}}
|
|
on:confirmed={() => {
|
|
if (indexToRemove !== undefined) {
|
|
removeAtIndex(indexToRemove)
|
|
indexToRemove = undefined
|
|
}
|
|
}}
|
|
/>
|
|
|
|
<style>
|
|
.badge {
|
|
@apply whitespace-nowrap text-sm font-medium border px-2.5 py-0.5 rounded cursor-pointer flex items-center;
|
|
}
|
|
|
|
.badge-on {
|
|
@apply bg-blue-100 text-blue-800 hover:bg-blue-200;
|
|
}
|
|
|
|
.badge-off {
|
|
@apply bg-gray-100 text-gray-800 hover:bg-gray-200;
|
|
}
|
|
</style>
|