feat(frontend): Add script editor tour

This commit is contained in:
Ádám Kovács
2023-03-10 09:38:34 +01:00
parent 4453690521
commit bfe5b56c99
8 changed files with 414 additions and 34 deletions
+56 -26
View File
@@ -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', () => {
@@ -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
}
@@ -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
}
@@ -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
}