Files
windmill/frontend/src/lib/components/home/TutorialButton.svelte
T
Tristan TR 3699ce7a8f feat: new live onboarding for flows (#7194)
* Start workspace onboarding

* Add pictures to tutorial steps

* Remove unecessary step

* Continue tutorial by creating a flow together

* Add image into the Create Flow tutorial pop up

* Generate flow from frontend

* Set pause between each node

* Add automatic scripts overview

* Simplify tutorial, and add step to show the code

* Add input step

* Autoremove last step after 5 seconds

* Add flow typing when opening code editor

* Remove lock field from json file

* Add Guides tab on left menu

* Add /guides page

* Add tutorial card in Guides tab

* Add step to show data connector

* Add second text input to show 2 types of inputs and fill them dynamically

* Improve tutorial chronology

* Add flow input connexion with first sctript

* Improve overlay

* Improve wording

* Add new tutorial step to show node b

* Add test step

* Add cursor to pick typescript

* Improve end of tutorial

* Refactor

* Highlight bottom right corner for 5 and 6

* Fix last step overlay

* change home tutorial button

* guidelines nits

* Automate onNext() trigger on step 3

* Improve fakr cursor for Test this step button

* Improve overlay transitions

* Merge data connectors and test step steps

* Improve live code writing in step 3

* Add a step to complete the flow

* Improve the step where we generate remaining scripts

* Refactor

* Add blocking behavior on step 3

* nit about delay

* Prevent clicking on Next while code not generated

* Sharpen wordings

* Remove Svelte 4 and migrate to Svelte 5

* Remove unecesary helper function

* Add toast if the user clicks on Next button before code finished generating

* Add toasts to each step

* Improve tutorial trigger timing

* Improve delays

* Add cursor movement to Test Flow button

* Block previous on certain steps to prevent bug

* Fix for github npm check

* Fix for github npm check

* Unlike workspace onboarding and flow tutorial

* Rename flow tutorial with better name

* Remove the automatic trigger for flow previous and broken tutorial

* Push tutorials to Help sectionof the sidebar

* Fix redirection t /tutorials page

* Add tutorials page and update workspace onboarding flow

- Rename guides to tutorials page (/tutorials)
- Add workspace onboarding tutorial to tutorials page
- Remove Tutorial button from homepage
- Add welcome cards for empty workspace with 3 tutorial options
- Update workspace onboarding to redirect to homepage before starting
- Clean up URL parameter after tutorial completion
- Move Tutorials to Help menu in sidebar
- Remove automatic "action" tutorial trigger for new flows
- Add flow-live-tutorial (renamed from workspace-onboarding-continue)
- Add Previous button blocking with toast notifications in flow tutorial

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add tutorials to workspace homepage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Start tutorials for Run/logs section

* Fix data connector

* Add flow execution graph from Run drawer

* Add tabs highlighting in drawer

* Improve tutorial on run drawer

* Add mouse cursor moving from graph tab

* Add cursor click on script in Drawer Graph tabs

* Add troubleshooting flow in tutorial

* Add step to show logs of failed step

* add step 7 to invite the user to fix by himself and se the new results

* Improve wording

* Nit improvements

* Nits

* Refactor

* Refactor

* Rename the tutorial

* Remove deleted file

* Improve wording

* Improve first step of troubleshooting flow tutorial

* Add tutorials to /tutorials page and create component

* Remove previous Flow tutorials

* Fixes, and improve tutorial button design

* Improve status in Tutorial button

* Align tutorial button to brand guidelines

* Add skip all to onboarding workspace tutorial

* Add skipped_all to tutorial_progress

* Connect backend and frontend for tutorial progress

* Add store and helper to display or not Tutorials from left menu

* Add reminder at the end of each tutorial

* Add tutorial banner

* Remove tutorials from elpty workspace

* Improve Tutorials page

* Align banner to guidelines

* Add reset tutorials buttons

* Refactor

* Refactor to make it easy to add new tutorials and tabs

* Improve tutorial config to make it easy to add new tutorials

* Refactor and remove hardcoded indexes

* Add getTutorialIndex in tutorial config file

* Nit

* Add Mark all as complete button in tutorial page

* Add skip tutorial button in banner toast

* Replace if else in tutorials router by map to make it easier to maintain and scale

* Delete broken simple app tutorial

* Add Guide flow guide buttons inside the Create Flow page

* Add flow editor tutorials into flow builder page

* Update existing app tutorials with new tutorial system

* Create a dedicated tutorial category for app editor

* Add global progress bar

* Add Reset & Skip at tutorial category level

* Add progress to tab title

* Nits on design

* Make progress bar a props and design nits

* Add active props for Tutorial Category

* Display tutorials according to the user role

* Adapt progress bar to the user role

* Add roles array for each tutorial

* Add Tutorials tab in Operator menu

* Edge case if no Category and no Tutorial available for my role

* Allow the user to reset a single tutorial

* Allow a user to mark as completed a single tutorial

* Nit on hoovering tutorial status

* Allow admins to see which tutorials are available per role

* Create utils that allow admins to see which tutorials can access other roles of their organization

* Refactor resetSingleTutorial and completeSingleTutorial into one function

* Improve role system

* Remove hardcoded MAX_TUTORIAL_ID

* Fix type assertion

* Remove console log

* Reduce recalculations when unrelated state changes

* Add console.error

* Remove unused function

* Add tutorial wrapper and better router

* Nits to pass npm checks

* Fix typescripts and lint errors

* Add SQLx query cache for tutorial_progress queries

* Improve wording for workspace tutorial

---------

Co-authored-by: Diego Imbert <diego@windmill.dev>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2025-12-08 16:42:35 +00:00

125 lines
3.1 KiB
Svelte

<script lang="ts">
import { CheckCircle2, Circle, RefreshCw, CheckCheck } from 'lucide-svelte'
import type { ComponentType } from 'svelte'
interface Props {
icon: ComponentType
title: string
description: string
onclick: () => void
isCompleted?: boolean
disabled?: boolean
comingSoon?: boolean
onReset?: () => void
onComplete?: () => void
}
let {
icon: Icon,
title,
description,
onclick,
isCompleted = false,
disabled = false,
comingSoon = false,
onReset,
onComplete
}: Props = $props()
let isHovered = $state(false)
// Determine which action button to show
const actionButton = $derived(() => {
if (isCompleted && isHovered && onReset) {
return {
icon: RefreshCw,
label: 'Reset',
onClick: onReset
}
}
if (!isCompleted && isHovered && onComplete) {
return {
icon: CheckCheck,
label: 'Mark as completed',
onClick: onComplete
}
}
return null
})
function handleAction(e: MouseEvent | KeyboardEvent) {
const button = actionButton()
if (!button) return
e.stopPropagation()
e.preventDefault()
button.onClick()
}
</script>
<button
onclick={disabled || comingSoon ? undefined : onclick}
disabled={disabled || comingSoon}
class="group relative flex items-center gap-4 w-full px-4 py-3 first-of-type:!border-t-0 first-of-type:rounded-t-md last-of-type:rounded-b-md [*:not(:last-child)]:border-b border-b border-light transition-colors text-left last:border-b-0 {disabled || comingSoon
? 'opacity-50 cursor-not-allowed'
: 'hover:bg-surface-hover'}"
>
<!-- Icon -->
<Icon size={20} class="flex-shrink-0 text-accent-primary transition-colors" />
<!-- Content -->
<div class="flex-1 min-w-0">
<div class="text-emphasis flex-wrap text-left text-xs font-semibold {!disabled && !comingSoon
? 'group-hover:text-accent-primary'
: ''} transition-colors">
{title}
{#if comingSoon}
<span class="ml-2 text-3xs text-secondary">(Coming soon)</span>
{/if}
</div>
<div class="text-hint text-3xs truncate text-left font-normal">
{description}
</div>
</div>
<!-- Status -->
<div
role="status"
class="flex items-center gap-1.5 flex-shrink-0"
onmouseenter={() => (isHovered = true)}
onmouseleave={() => (isHovered = false)}
>
{#if actionButton()}
{@const button = actionButton()!}
{@const ActionIcon = button.icon}
<div
role="button"
tabindex="0"
onclick={handleAction}
onkeydown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleAction(e)
}
}}
class="flex items-center gap-1.5 px-2 py-1 text-xs font-normal text-secondary hover:text-primary hover:bg-surface-hover rounded transition-colors cursor-pointer"
>
<ActionIcon size={14} class="flex-shrink-0" />
{button.label}
</div>
{:else}
<span
class="text-xs font-normal {isCompleted
? 'text-green-500'
: 'text-blue-300'}"
>
{isCompleted ? 'Completed' : 'Not started'}
</span>
{#if isCompleted}
<CheckCircle2 size={14} class="text-green-500 flex-shrink-0" />
{:else}
<Circle size={14} class="text-blue-300 flex-shrink-0" />
{/if}
{/if}
</div>
</button>