mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 08:02:43 +00:00
feat(frontend): added list of triggers in the flow graph
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
import { encodeState } from '$lib/utils'
|
||||
import BranchOneStart from './renderers/nodes/BranchOneStart.svelte'
|
||||
import NoBranchNode from './renderers/nodes/NoBranchNode.svelte'
|
||||
import HiddenBaseEdge from './renderers/edges/HiddenBaseEdge.svelte'
|
||||
|
||||
export let success: boolean | undefined = undefined
|
||||
export let modules: FlowModule[] | undefined = []
|
||||
@@ -42,6 +43,7 @@
|
||||
export let flowModuleStates: Record<string, GraphModuleState> | undefined = undefined
|
||||
|
||||
export let selectedId: Writable<string | undefined> = writable<string | undefined>(undefined)
|
||||
export let path: string | undefined = undefined
|
||||
|
||||
export let insertable = false
|
||||
export let moving: string | undefined = undefined
|
||||
@@ -126,7 +128,8 @@
|
||||
disableAi,
|
||||
insertable,
|
||||
flowModuleStates,
|
||||
selectedId: $selectedId
|
||||
selectedId: $selectedId,
|
||||
path
|
||||
},
|
||||
failureModule,
|
||||
{
|
||||
@@ -199,7 +202,8 @@
|
||||
const edgeTypes = {
|
||||
edge: BaseEdge,
|
||||
empty: EmptyEdge,
|
||||
dataflowedge: DataflowEdge
|
||||
dataflowedge: DataflowEdge,
|
||||
hiddenedge: HiddenBaseEdge
|
||||
} as any
|
||||
|
||||
const proOptions = { hideAttribution: true }
|
||||
|
||||
@@ -107,6 +107,22 @@ export default function graphBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
if (extra.path) {
|
||||
const triggerNode: Node = {
|
||||
id: 'Trigger',
|
||||
position: { x: -1, y: -1 },
|
||||
type: 'trigger',
|
||||
data: {
|
||||
path: extra.path
|
||||
}
|
||||
}
|
||||
|
||||
nodes.push(triggerNode)
|
||||
addEdge('Trigger', 'Input', {
|
||||
type: 'hiddenedge'
|
||||
})
|
||||
}
|
||||
|
||||
const resultNode: Node = {
|
||||
id: 'result',
|
||||
data: {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { BaseEdge } from '@xyflow/svelte'
|
||||
export let markerEnd: string | undefined = undefined
|
||||
</script>
|
||||
|
||||
<BaseEdge path={''} {markerEnd} class="hidden" />
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<NodeWrapper enableTargetHandle={false} let:darkMode>
|
||||
{#if data.insertable && !data.disableAi}
|
||||
<div class="absolute -top-10 left-1/2 transform -translate-x-1/2 z-10">
|
||||
<div class="absolute -top-8 left-1/2 transform -translate-x-1/2 z-10">
|
||||
<Popover>
|
||||
<div class={openNoCopilot ? 'z-10' : ''}>
|
||||
<Menu pointerDown noMinW placement="bottom-center" let:close bind:show={openNoCopilot}>
|
||||
@@ -46,9 +46,9 @@
|
||||
: undefined}
|
||||
slot="trigger"
|
||||
type="button"
|
||||
class=" bg-surface text-violet-800 dark:text-violet-400 border mx-0.5 focus:outline-none hover:bg-surface-hover focus:ring-4 focus:ring-gray-200 font-medium rounded-full text-sm w-8 h-8 flex items-center justify-center"
|
||||
class=" bg-surface text-violet-800 dark:text-violet-400 border mx-0.5 focus:outline-none hover:bg-surface-hover focus:ring-4 focus:ring-gray-200 font-medium rounded-full text-sm w-6 h-6 flex items-center justify-center"
|
||||
>
|
||||
<Wand2 size={16} />
|
||||
<Wand2 size={14} />
|
||||
</button>
|
||||
{#if !$copilotInfo.exists_openai_resource_path}
|
||||
<div class="text-primary p-4">
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
<script lang="ts">
|
||||
import DarkModeObserver from '$lib/components/DarkModeObserver.svelte'
|
||||
import { Handle, Position } from '@xyflow/svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export let enableSourceHandle: boolean = true
|
||||
export let enableTargetHandle: boolean = true
|
||||
export let offset: number = 0
|
||||
export let wrapperClass: string = ''
|
||||
|
||||
let darkMode: boolean = false
|
||||
</script>
|
||||
|
||||
<DarkModeObserver bind:darkMode />
|
||||
|
||||
<div class="relative shadow-md" style={`margin-left: ${offset}px;`}>
|
||||
<div class={twMerge('relative shadow-md', wrapperClass)} style={`margin-left: ${offset}px;`}>
|
||||
<slot {darkMode} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import NodeWrapper from './NodeWrapper.svelte'
|
||||
import TriggersWrapper from '../triggers/TriggersWrapper.svelte'
|
||||
</script>
|
||||
|
||||
<NodeWrapper wrapperClass="shadow-none">
|
||||
<TriggersWrapper />
|
||||
</NodeWrapper>
|
||||
@@ -0,0 +1,14 @@
|
||||
<script>
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
</script>
|
||||
|
||||
<button
|
||||
on:click
|
||||
class={twMerge(
|
||||
'bg-surface-secondary hover:bg-surface-hover rounded-md border text-xs',
|
||||
'w-6 h-6',
|
||||
'relative center-center'
|
||||
)}
|
||||
>
|
||||
<slot />
|
||||
</button>
|
||||
@@ -0,0 +1,121 @@
|
||||
<script lang="ts">
|
||||
import { Calendar, Mail, Webhook } from 'lucide-svelte'
|
||||
import TriggerButton from './TriggerButton.svelte'
|
||||
import { NODE } from '../../util'
|
||||
import { ScheduleService, type Schedule } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import Popover from '$lib/components/Popover.svelte'
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import { DrawerContent, Tabs } from '$lib/components/common'
|
||||
import WebhooksPanel from '$lib/components/details/WebhooksPanel.svelte'
|
||||
import Tab from '$lib/components/common/tabs/Tab.svelte'
|
||||
import EmailTriggerPanel from '$lib/components/details/EmailTriggerPanel.svelte'
|
||||
import type { FlowEditorContext } from '$lib/components/flows/types'
|
||||
import { getContext } from 'svelte'
|
||||
import TriggerCount from './TriggerCount.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
let schedules: Schedule[] | undefined = undefined
|
||||
const { selectedId, pathStore } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
async function loadSchedules() {
|
||||
if (!$pathStore) return
|
||||
try {
|
||||
schedules = await ScheduleService.listSchedules({
|
||||
workspace: $workspaceStore ?? '',
|
||||
path: $pathStore,
|
||||
isFlow: true
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('impossible to load schedules')
|
||||
}
|
||||
}
|
||||
loadSchedules()
|
||||
let drawer: Drawer | undefined = undefined
|
||||
let selectedTab: 'webhooks' | 'mail' = 'webhooks'
|
||||
</script>
|
||||
|
||||
<Drawer bind:this={drawer} size="600px">
|
||||
<DrawerContent
|
||||
title="Triggers"
|
||||
noPadding
|
||||
on:close={drawer.closeDrawer}
|
||||
tooltip="Resources represent connections to third party systems. Learn more on how to integrate external APIs."
|
||||
documentationLink="https://www.windmill.dev/docs/integrations/integrations_on_windmill"
|
||||
>
|
||||
<Tabs bind:selected={selectedTab}>
|
||||
<Tab value="webhooks">Webhooks</Tab>
|
||||
<Tab value="mail">Mail</Tab>
|
||||
<svelte:fragment slot="content">
|
||||
{#if selectedTab === 'webhooks'}
|
||||
<WebhooksPanel
|
||||
scopes={[`run:flow/${$pathStore}`]}
|
||||
path={$pathStore}
|
||||
isFlow={true}
|
||||
args={{}}
|
||||
token=""
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if selectedTab === 'mail'}
|
||||
<EmailTriggerPanel
|
||||
token=""
|
||||
scopes={[`run:flow/${$pathStore}`]}
|
||||
path={$pathStore}
|
||||
isFlow={true}
|
||||
/>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Tabs>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<div style={`width: ${NODE.width}px;`}>
|
||||
<div class="flex flex-col mx-auto w-min">
|
||||
<div
|
||||
class="flex flex-row gap-2 px-2 border p-1 rounded-md border-surface-selected bg-surface shadow-md items-center"
|
||||
>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-row items-center text-2xs">
|
||||
Triggers
|
||||
|
||||
<Tooltip small wrapperClass="center-center">
|
||||
The flow can be triggered by webhooks, emails, or schedules. Click on the icons to see
|
||||
the triggers.
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<Popover>
|
||||
<svelte:fragment slot="text">See default webhooks triggers</svelte:fragment>
|
||||
<TriggerButton
|
||||
on:click={() => {
|
||||
selectedTab = 'webhooks'
|
||||
drawer?.openDrawer()
|
||||
}}
|
||||
>
|
||||
<Webhook size={12} />
|
||||
</TriggerButton>
|
||||
</Popover>
|
||||
<Popover>
|
||||
<svelte:fragment slot="text">See default mail trigger</svelte:fragment>
|
||||
<TriggerButton
|
||||
on:click={() => {
|
||||
selectedTab = 'mail'
|
||||
drawer?.openDrawer()
|
||||
}}
|
||||
>
|
||||
<Mail size={12} />
|
||||
</TriggerButton>
|
||||
</Popover>
|
||||
<Popover>
|
||||
<svelte:fragment slot="text">See all schedules</svelte:fragment>
|
||||
<TriggerButton
|
||||
on:click={() => {
|
||||
$selectedId = 'settings-schedule'
|
||||
}}
|
||||
>
|
||||
<TriggerCount count={schedules?.length} />
|
||||
<Calendar size={12} />
|
||||
</TriggerButton>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user