mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 16:02:14 +00:00
Fix flow tutorials (#6722)
* Fix tutorial basic * fix other tutorials * nit fix bug with button shrinking * tutorial works backwards * nit delete field on prev
This commit is contained in:
@@ -643,7 +643,8 @@
|
||||
|
||||
{#if !uiOnly}
|
||||
<button
|
||||
class="rounded-full p-1 text-gray-500 bg-white
|
||||
class="delete-schema-field-button
|
||||
rounded-full p-1 text-gray-500 bg-white
|
||||
duration-200 hover:bg-gray-600 focus:bg-gray-600 hover:text-white dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800"
|
||||
aria-label="Clear"
|
||||
onclick={() => {
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
use:clickOutside={{
|
||||
eventToListenName: 'pointerdown',
|
||||
stopPropagation: true,
|
||||
exclude: async () => {
|
||||
const tutorial = document.querySelector('#driver-popover-content') as HTMLElement | null
|
||||
if (tutorial) return [tutorial]
|
||||
return []
|
||||
},
|
||||
onClickOutside: () => (open = false)
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -109,8 +109,9 @@
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Index 0 is used by the tutorial to identify the first "Add step" -->
|
||||
<InsertModuleButton
|
||||
index={0}
|
||||
index="error-handler-button"
|
||||
placement={'bottom-center'}
|
||||
on:new={(e) => {
|
||||
insertFailureModule(e.detail.inlineScript)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
type Placement = `${Side}-${Alignment}`
|
||||
|
||||
interface Props {
|
||||
index?: number
|
||||
index?: number | 'error-handler-button'
|
||||
funcDesc?: string
|
||||
kind?: 'script' | 'trigger' | 'preprocessor' | 'failure'
|
||||
iconSize?: number
|
||||
|
||||
@@ -51,14 +51,14 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#flow-editor-error-handler',
|
||||
element: '#flow-editor-add-step-error-handler-button',
|
||||
popover: {
|
||||
title: 'Error handler',
|
||||
description:
|
||||
'You can add an error handler to your flow. It will be executed if any of the steps in the flow fails.',
|
||||
|
||||
onNextClick: () => {
|
||||
triggerPointerDown('#flow-editor-error-handler button')
|
||||
triggerPointerDown('#flow-editor-add-step-error-handler-button')
|
||||
setTimeout(() => {
|
||||
driver.moveNext()
|
||||
})
|
||||
|
||||
@@ -178,6 +178,9 @@
|
||||
|
||||
{
|
||||
element: '#flow-editor-step-input',
|
||||
onHighlighted: () => {
|
||||
document.querySelector('#flow-editor-plug')?.parentElement?.classList.remove('opacity-0')
|
||||
},
|
||||
popover: {
|
||||
title: 'Flow inputs',
|
||||
description: 'UI is autogenerated from your code.'
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
} from './utils'
|
||||
import Tutorial from './Tutorial.svelte'
|
||||
import { refreshStateStore } from '$lib/svelte5Utils.svelte'
|
||||
import { wait } from '$lib/utils'
|
||||
|
||||
const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -41,16 +42,13 @@
|
||||
popover: {
|
||||
title: 'Flows inputs',
|
||||
description: 'Flows have inputs that can be used in the flow',
|
||||
onNextClick: () => {
|
||||
clickButtonBySelector('#flow-editor-virtual-Input')
|
||||
tick()
|
||||
.then(() => clickButtonBySelector('#add-flow-input-btn'))
|
||||
.then(tick)
|
||||
.then(() => setInputBySelector('input[placeholder="Field name"]', 'firstname'))
|
||||
|
||||
setTimeout(() => {
|
||||
driver.moveNext()
|
||||
})
|
||||
onNextClick: async () => {
|
||||
triggerPointerDown('#flow-editor-virtual-Input')
|
||||
await wait(20)
|
||||
clickButtonBySelector('#add-flow-input-btn')
|
||||
await wait(0)
|
||||
setInputBySelector('input[placeholder="Field name"]', 'firstname')
|
||||
setTimeout(() => driver.moveNext())
|
||||
}
|
||||
},
|
||||
element: '#flow-editor-virtual-Input'
|
||||
@@ -64,11 +62,15 @@
|
||||
setTimeout(() => {
|
||||
driver.moveNext()
|
||||
})
|
||||
},
|
||||
onPrevClick: () => {
|
||||
clickButtonBySelector('#add-flow-input-btn') // Close the input drawer
|
||||
setTimeout(() => driver.movePrevious())
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
element: '#flow-editor-add-property',
|
||||
element: '*:has(> #flow-editor-add-property)',
|
||||
popover: {
|
||||
title: 'Add your property',
|
||||
description: 'Click here to save your property',
|
||||
@@ -87,16 +89,26 @@
|
||||
description: 'Click here to add a step to your flow',
|
||||
onNextClick: () => {
|
||||
triggerPointerDown(`#flow-editor-add-step-0`)
|
||||
setTimeout(() => {
|
||||
driver.moveNext()
|
||||
})
|
||||
setTimeout(() => driver.moveNext())
|
||||
},
|
||||
onPrevClick: async () => {
|
||||
clickButtonBySelector('.delete-schema-field-button')
|
||||
await wait(0)
|
||||
clickButtonBySelector('#add-flow-input-btn')
|
||||
await wait(0)
|
||||
setInputBySelector('input[placeholder="Field name"]', 'firstname')
|
||||
setTimeout(() => driver.movePrevious())
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
popover: {
|
||||
title: 'Steps kind',
|
||||
description: "Choose the kind of step you want to add. Let's start with a simple action"
|
||||
description: "Choose the kind of step you want to add. Let's start with a simple action",
|
||||
onPrevClick: () => {
|
||||
triggerPointerDown(`#flow-editor-add-step-0`)
|
||||
setTimeout(() => driver.movePrevious())
|
||||
}
|
||||
},
|
||||
element: '#flow-editor-insert-module'
|
||||
},
|
||||
@@ -149,6 +161,7 @@
|
||||
title: 'Action editor',
|
||||
description: 'Windmill provides a full code editor to write your actions',
|
||||
onPrevClick: () => {
|
||||
triggerPointerDown(`#flow-editor-virtual-Input`)
|
||||
triggerPointerDown(`#flow-editor-add-step-0`)
|
||||
setTimeout(() => {
|
||||
driver.movePrevious()
|
||||
@@ -158,6 +171,9 @@
|
||||
},
|
||||
{
|
||||
element: '#flow-editor-step-input',
|
||||
onHighlighted: () => {
|
||||
document.querySelector('#flow-editor-plug')?.parentElement?.classList.remove('opacity-0')
|
||||
},
|
||||
popover: {
|
||||
title: 'Autogenerated schema',
|
||||
description: 'The schema and the UI is autogenerated from your code'
|
||||
@@ -165,10 +181,14 @@
|
||||
},
|
||||
{
|
||||
element: '#flow-editor-plug',
|
||||
onHighlighted: () => {
|
||||
document.querySelector('#flow-editor-plug')?.parentElement?.classList.remove('opacity-0')
|
||||
},
|
||||
popover: {
|
||||
title: 'Connect',
|
||||
description:
|
||||
'You can provide static values or connect to other nodes result. Here we will connect to the firstname input',
|
||||
|
||||
onNextClick: () => {
|
||||
clickButtonBySelector('#flow-editor-plug')
|
||||
setTimeout(() => {
|
||||
@@ -198,6 +218,10 @@
|
||||
setTimeout(() => {
|
||||
driver.moveNext()
|
||||
})
|
||||
},
|
||||
onPrevClick: () => {
|
||||
clickButtonBySelector('#flow-editor-plug')
|
||||
setTimeout(() => driver.movePrevious())
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -206,7 +230,11 @@
|
||||
element: '#flow-editor-step-input',
|
||||
popover: {
|
||||
title: 'Input connected!',
|
||||
description: 'The input is now connected to the firstname input'
|
||||
description: 'The input is now connected to the firstname input',
|
||||
onPrevClick: () => {
|
||||
clickButtonBySelector('#flow-editor-plug')
|
||||
setTimeout(() => driver.movePrevious())
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -226,7 +254,7 @@
|
||||
},
|
||||
|
||||
{
|
||||
element: '#flow-preview-content',
|
||||
element: 'textarea.w-full',
|
||||
popover: {
|
||||
title: 'Flow input',
|
||||
description: 'Let’s provide an input to our flow',
|
||||
@@ -236,6 +264,10 @@
|
||||
setTimeout(() => {
|
||||
driver.moveNext()
|
||||
})
|
||||
},
|
||||
onPrevClick: () => {
|
||||
clickButtonBySelector('#flow-editor-test-flow') // Close the test drawer
|
||||
setTimeout(() => driver.movePrevious())
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
// Render controls needs to be exposed so steps that have a custom render can call it
|
||||
export function renderControls({ config, state }) {
|
||||
const popoverContent = document.querySelector('#driver-popover-content')
|
||||
popoverContent?.addEventListener('pointerdown', (event) => {
|
||||
event.stopPropagation()
|
||||
})
|
||||
|
||||
const popoverDescription = document.querySelector('#driver-popover-description')
|
||||
|
||||
if (!tutorial) {
|
||||
|
||||
@@ -172,9 +172,9 @@ export function displayDate(
|
||||
}
|
||||
const dateChoices: Intl.DateTimeFormatOptions = displayDate
|
||||
? {
|
||||
day: 'numeric',
|
||||
month: 'numeric'
|
||||
}
|
||||
day: 'numeric',
|
||||
month: 'numeric'
|
||||
}
|
||||
: {}
|
||||
return date.toLocaleString(undefined, {
|
||||
...timeChoices,
|
||||
@@ -1065,7 +1065,7 @@ export async function tryEvery({
|
||||
try {
|
||||
await tryCode()
|
||||
break
|
||||
} catch (err) { }
|
||||
} catch (err) {}
|
||||
i++
|
||||
}
|
||||
if (i >= times) {
|
||||
@@ -1331,7 +1331,7 @@ export function conditionalMelt(node: HTMLElement, meltItem: AnyMeltElement | un
|
||||
if (meltItem) {
|
||||
return meltItem(node)
|
||||
}
|
||||
return { destroy: () => { } }
|
||||
return { destroy: () => {} }
|
||||
}
|
||||
|
||||
export type Item = {
|
||||
@@ -1537,9 +1537,9 @@ export type S3Uri = `s3://${string}/${string}`
|
||||
export type S3Object =
|
||||
| S3Uri
|
||||
| {
|
||||
s3: string
|
||||
storage?: string
|
||||
}
|
||||
s3: string
|
||||
storage?: string
|
||||
}
|
||||
|
||||
export function parseS3Object(s3Object: S3Object): { s3: string; storage?: string } {
|
||||
if (typeof s3Object === 'object') return s3Object
|
||||
@@ -1620,3 +1620,7 @@ export function createCache<Keys extends Record<string, any>, T, InitialKeys ext
|
||||
return cache.get(key)!.value
|
||||
}
|
||||
}
|
||||
|
||||
export async function wait(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(() => resolve(undefined), ms))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user