feat(frontend): Add script editor tour
This commit is contained in:
@@ -232,8 +232,14 @@
|
||||
<Badge color={validCode ? 'green' : 'red'} class="min-w-[60px] mr-3">
|
||||
{validCode ? 'Valid' : 'Invalid'}
|
||||
</Badge>
|
||||
<div class="flex items-center divide-x">
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="pr-1" disablePopup={!iconOnly}>
|
||||
<div id="script-tutorial-3" class="flex items-center divide-x">
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="pr-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
color="light"
|
||||
btnClasses="!font-medium !h-full"
|
||||
@@ -245,11 +251,15 @@
|
||||
>
|
||||
+Context Var
|
||||
</Button>
|
||||
<svelte:fragment slot="text">
|
||||
Add context variable
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="text">Add context variable</svelte:fragment>
|
||||
</Popover>
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="px-1" disablePopup={!iconOnly}>
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="px-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
color="light"
|
||||
btnClasses="!font-medium !h-full"
|
||||
@@ -261,11 +271,15 @@
|
||||
>
|
||||
+Variable
|
||||
</Button>
|
||||
<svelte:fragment slot="text">
|
||||
Add variable
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="text">Add variable</svelte:fragment>
|
||||
</Popover>
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="px-1" disablePopup={!iconOnly}>
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="px-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
btnClasses="!font-medium !h-full"
|
||||
size="xs"
|
||||
@@ -277,11 +291,15 @@
|
||||
>
|
||||
+Resource
|
||||
</Button>
|
||||
<svelte:fragment slot="text">
|
||||
Add resource
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="text">Add resource</svelte:fragment>
|
||||
</Popover>
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="px-1" disablePopup={!iconOnly}>
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="px-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
btnClasses="!font-medium !h-full"
|
||||
size="xs"
|
||||
@@ -293,11 +311,15 @@
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
<svelte:fragment slot="text">
|
||||
Reset
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="text">Reset</svelte:fragment>
|
||||
</Popover>
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="px-1" disablePopup={!iconOnly}>
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="px-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
btnClasses="!font-medium !h-full"
|
||||
size="xs"
|
||||
@@ -320,11 +342,15 @@
|
||||
{/if}
|
||||
</span>
|
||||
</Button>
|
||||
<svelte:fragment slot="text">
|
||||
Reload assistant
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="text">Reload assistant</svelte:fragment>
|
||||
</Popover>
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="px-1" disablePopup={!iconOnly}>
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="px-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
btnClasses="!font-medium"
|
||||
size="xs"
|
||||
@@ -342,7 +368,13 @@
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<Popover notClickable placement="bottom" disapperTimoout={0} class="px-1" disablePopup={!iconOnly}>
|
||||
<Popover
|
||||
notClickable
|
||||
placement="bottom"
|
||||
disapperTimoout={0}
|
||||
class="px-1"
|
||||
disablePopup={!iconOnly}
|
||||
>
|
||||
<Button
|
||||
btnClasses="!font-medium"
|
||||
size="xs"
|
||||
@@ -354,9 +386,7 @@
|
||||
>
|
||||
Script
|
||||
</Button>
|
||||
<svelte:fragment slot="text">
|
||||
Script
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="text">Script</svelte:fragment>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -350,6 +350,7 @@
|
||||
lang={script.language}
|
||||
{initialArgs}
|
||||
{kind}
|
||||
tour
|
||||
/>
|
||||
{:else if step === 3}
|
||||
<CenteredPage>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { Button, Kbd } from './common'
|
||||
import SplitPanesWrapper from './splitPanes/SplitPanesWrapper.svelte'
|
||||
import WindmillIcon from './icons/WindmillIcon.svelte'
|
||||
import { Tour } from './tutorial'
|
||||
|
||||
// Exported
|
||||
export let schema: Schema = emptySchema()
|
||||
@@ -27,6 +28,7 @@
|
||||
export let initialArgs: Record<string, any> = {}
|
||||
export let fixedOverflowWidgets = true
|
||||
export let noSyncFromGithub = false
|
||||
export let tour = false
|
||||
|
||||
let websocketAlive = { pyright: false, black: false, deno: false, go: false }
|
||||
|
||||
@@ -114,6 +116,10 @@
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
{#if tour}
|
||||
<Tour tutorial="script" />
|
||||
{/if}
|
||||
|
||||
<div class="border-b-2 shadow-sm px-1 pr-4" bind:clientWidth={width}>
|
||||
<div class="flex justify-between space-x-2">
|
||||
<EditorBar
|
||||
@@ -146,6 +152,7 @@
|
||||
<Splitpanes class="!overflow-visible">
|
||||
<Pane size={60} minSize={10} class="!overflow-visible">
|
||||
<div
|
||||
id="script-tutorial-1"
|
||||
class="pl-2 h-full !overflow-visible"
|
||||
on:mouseleave={() => {
|
||||
inferSchema(code)
|
||||
@@ -180,7 +187,7 @@
|
||||
</Pane>
|
||||
<Pane size={40} minSize={10}>
|
||||
<div class="flex flex-col h-full">
|
||||
<div class="px-2 w-full border-b py-1">
|
||||
<div id="script-tutorial-4" class="px-2 w-full border-b py-1">
|
||||
{#if testIsLoading}
|
||||
<Button on:click={testJobLoader?.cancelJob} btnClasses="w-full" color="red" size="xs">
|
||||
<WindmillIcon
|
||||
@@ -211,7 +218,7 @@
|
||||
</div>
|
||||
<Splitpanes horizontal class="!max-h-[calc(100%-43px)]">
|
||||
<Pane size={33}>
|
||||
<div class="px-2">
|
||||
<div id="script-tutorial-2" class="px-2">
|
||||
<div class="break-words relative font-sans">
|
||||
<SchemaForm compact {schema} bind:args bind:isValid />
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* If the index of a step is added to a tour, the custom footer will not be added
|
||||
* (ie. the steps won't be shown and the buttons won't be positioned)
|
||||
*/
|
||||
const noCustomFooter: Partial<Record<TutorialName, number[]>> = {
|
||||
const noPageNumber: Partial<Record<TutorialName, number[]>> = {
|
||||
welcome: [0]
|
||||
}
|
||||
let tour: Shepherd.Tour | undefined
|
||||
@@ -25,7 +25,7 @@
|
||||
})
|
||||
tour.addSteps(steps[tutorial](tour))
|
||||
tour.steps.forEach((step, i) => {
|
||||
if (noCustomFooter[tutorial]?.includes(i)) {
|
||||
if (noPageNumber[tutorial]?.includes(i)) {
|
||||
return
|
||||
}
|
||||
step.on('show', () => {
|
||||
|
||||
113
frontend/src/lib/components/tutorial/app-steps.ts
Normal file
113
frontend/src/lib/components/tutorial/app-steps.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import type Shepherd from 'shepherd.js'
|
||||
|
||||
export default (tour: Shepherd.Tour) => {
|
||||
const steps: object[] | Shepherd.Step[] = [
|
||||
{
|
||||
id: 'welcome',
|
||||
text: `<div class="text-xl font-bold mb-6">Windmill Script Builder</div>
|
||||
<p class="mb-6">Build scripts with out own web editor, then use them anywhere in your flows, apps or as standalone computations with their auto-generated UI.</p>`,
|
||||
buttons: [
|
||||
{
|
||||
text: 'See by myself',
|
||||
action: tour.cancel,
|
||||
secondary: true,
|
||||
classes: 'special'
|
||||
},
|
||||
{
|
||||
text: 'Give me an overview',
|
||||
action: tour.next,
|
||||
classes: 'special'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'editor',
|
||||
text: `<div class="text-xl font-bold mb-2">Web editor</div>
|
||||
<p class="mb-2">Code directly from the web editor.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#app-tutorial-1', on: 'bottom-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'preview',
|
||||
text: `<div class="text-xl font-bold mb-2">UI preview</div>
|
||||
<p class="mb-2">Preview the user interface generated from the signature of the script.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#app-tutorial-2', on: 'left-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'parameters',
|
||||
text: `<div class="text-xl font-bold mb-2">Parameters</div>
|
||||
<p class="mb-2">Add variables, resources and configure your script.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#app-tutorial-3', on: 'bottom-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'test',
|
||||
text: `<div class="text-xl font-bold mb-2">Test script</div>
|
||||
<p class="mb-2">Time to try your work! Test the script and iterate as much as you want.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#app-tutorial-4', on: 'left-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Finish',
|
||||
action: tour.complete
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
return steps
|
||||
}
|
||||
113
frontend/src/lib/components/tutorial/flow-steps.ts
Normal file
113
frontend/src/lib/components/tutorial/flow-steps.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import type Shepherd from 'shepherd.js'
|
||||
|
||||
export default (tour: Shepherd.Tour) => {
|
||||
const steps: object[] | Shepherd.Step[] = [
|
||||
{
|
||||
id: 'welcome',
|
||||
text: `<div class="text-xl font-bold mb-6">Windmill Script Builder</div>
|
||||
<p class="mb-6">Build scripts with out own web editor, then use them anywhere in your flows, apps or as standalone computations with their auto-generated UI.</p>`,
|
||||
buttons: [
|
||||
{
|
||||
text: 'See by myself',
|
||||
action: tour.cancel,
|
||||
secondary: true,
|
||||
classes: 'special'
|
||||
},
|
||||
{
|
||||
text: 'Give me an overview',
|
||||
action: tour.next,
|
||||
classes: 'special'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'editor',
|
||||
text: `<div class="text-xl font-bold mb-2">Web editor</div>
|
||||
<p class="mb-2">Code directly from the web editor.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#flow-tutorial-1', on: 'bottom-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'preview',
|
||||
text: `<div class="text-xl font-bold mb-2">UI preview</div>
|
||||
<p class="mb-2">Preview the user interface generated from the signature of the script.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#flow-tutorial-2', on: 'left-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'parameters',
|
||||
text: `<div class="text-xl font-bold mb-2">Parameters</div>
|
||||
<p class="mb-2">Add variables, resources and configure your script.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#flow-tutorial-3', on: 'bottom-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'test',
|
||||
text: `<div class="text-xl font-bold mb-2">Test script</div>
|
||||
<p class="mb-2">Time to try your work! Test the script and iterate as much as you want.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#flow-tutorial-4', on: 'left-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Finish',
|
||||
action: tour.complete
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
return steps
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
import welcome from './welcome-steps'
|
||||
import type Shepherd from 'shepherd.js'
|
||||
import welcome from './welcome-steps'
|
||||
import script from './script-steps'
|
||||
import flow from './flow-steps'
|
||||
import app from './app-steps'
|
||||
|
||||
export { default as Tour } from './Tour.svelte'
|
||||
|
||||
export type TutorialName = 'welcome' | 'script' | 'flow' | 'app'
|
||||
export const steps: Record<TutorialName, (tour: Shepherd.Tour) => object[] | Shepherd.Step[]> = {
|
||||
welcome,
|
||||
script: (tour: Shepherd.Tour) => [],
|
||||
flow: (tour: Shepherd.Tour) => [],
|
||||
app: (tour: Shepherd.Tour) => []
|
||||
script,
|
||||
flow,
|
||||
app
|
||||
}
|
||||
|
||||
113
frontend/src/lib/components/tutorial/script-steps.ts
Normal file
113
frontend/src/lib/components/tutorial/script-steps.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import type Shepherd from 'shepherd.js'
|
||||
|
||||
export default (tour: Shepherd.Tour) => {
|
||||
const steps: object[] | Shepherd.Step[] = [
|
||||
{
|
||||
id: 'welcome',
|
||||
text: `<div class="text-xl font-bold mb-6">Windmill Script Builder</div>
|
||||
<p class="mb-6">Build scripts with our own web editor, then use them anywhere in your flows, apps or as standalone computations with their auto-generated UI.</p>`,
|
||||
buttons: [
|
||||
{
|
||||
text: 'See by myself',
|
||||
action: tour.cancel,
|
||||
secondary: true,
|
||||
classes: 'special'
|
||||
},
|
||||
{
|
||||
text: 'Give me an overview',
|
||||
action: tour.next,
|
||||
classes: 'special'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'editor',
|
||||
text: `<div class="text-xl font-bold mb-2">Web editor</div>
|
||||
<p class="mb-2">Code directly from the web editor.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#script-tutorial-1', on: 'right-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'preview',
|
||||
text: `<div class="text-xl font-bold mb-2">UI preview</div>
|
||||
<p class="mb-2">Preview the user interface generated from the signature of the script.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#script-tutorial-2', on: 'left-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'parameters',
|
||||
text: `<div class="text-xl font-bold mb-2">Parameters</div>
|
||||
<p class="mb-2">Add variables, resources and configure your script.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#script-tutorial-3', on: 'bottom-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Next',
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'test',
|
||||
text: `<div class="text-xl font-bold mb-2">Test script</div>
|
||||
<p class="mb-2">Time to try your work! Test the script and iterate as much as you want.</p>`,
|
||||
cancelIcon: {
|
||||
enabled: true
|
||||
},
|
||||
attachTo: { element: '#script-tutorial-4', on: 'left-start' },
|
||||
highlightClass: 'shepherd-highlighted-element',
|
||||
scrollTo: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Back',
|
||||
action: tour.back,
|
||||
secondary: true
|
||||
},
|
||||
{
|
||||
text: 'Finish',
|
||||
action: tour.complete
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
return steps
|
||||
}
|
||||
Reference in New Issue
Block a user