Files
windmill/frontend/src/lib/components/tutorials/Tutorial.svelte
T
310f37a682 feat: migrate to svelte5 + vite6 (#4813)
* runs on svelte 5

* Line component from svelte-chartjs

* Replaced all svelte-chartjs occurrences with custom wrapper

* Fix props mistake

* Fix illegal table structures

* self-closing-tags fix

* aria labels

* Fixed trivial warnings and errors

* @tanstack/svelte-table fix

* upgrade to vite 6

* svelte-kit sync before running svelte-check

* Remove on:clear which is actually on:removeAll and already handled by on:change

* fix worker tags not displaying in Autoscaling

* Try to fix svelte-kit sync not working during CI

* remove warnings

* Fix add flow page crashing

* access worldStore before assignment fix

* fix infinite recursions in App Editor

* Replaced JSON.stringify with proper deepEqual

* component mount api changed (no longer classes)

* fix ci errors

* Fix infinite loops in background runnable panel

* factored effect on deep equal logic in onObjChange

* fix "Add" not working in AgGrid Table

* Replaced legacy component.$set api

* Fix multiselect infinite value reaction

* Fix flow input fields resetting when opening their edit tab

* fix date input resetting when typing year

* Remove !p-0 affecting subgrid dotted borders

* fix missing debounceTemplate causing hundreds of updates

* Fix AgGrid action refreshes and disppearing

* resolve getItems generating random ids every rerun

* fix cannot access items before init

* fix sort lambda arguments being undefined

* Revert "Remove !p-0 affecting subgrid dotted borders"

This reverts commit c62809bb45d682a48376b071680645ed4e1c601b.

* fix input not updating in decision tree editor

* Update frontend/src/lib/components/schema/EditableSchemaWrapper.svelte

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Re-added padding affecting subgrid dotted borders (#5479)

* remove !p-0 in preset components

* removed extra padding on accordion tabs subgrid

* Fix non-reactive SchemaForm

* dirty fix for the oneOf bug

* Fix warnings and update svelte-exmarkdown for svelte 5

* fix dnd not working

* don't mount component like objects

---------

Co-authored-by: Diego Imbert <diegoimbert@protonmail.com>
Co-authored-by: Diego Imbert <70353967+diegoimbert@users.noreply.github.com>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2025-04-02 21:33:50 +00:00

144 lines
3.3 KiB
Svelte

<script lang="ts">
import { driver, type Driver, type DriveStep } from 'driver.js'
import 'driver.js/dist/driver.css'
import { createEventDispatcher, mount } from 'svelte'
import { updateProgress } from '$lib/tutorialUtils'
import { ignoredTutorials } from './ignoredTutorials'
import SkipTutorials from './SkipTutorials.svelte'
import TutorialControls from './TutorialControls.svelte'
export let index: number = 0
export let name: string = 'action'
export let tainted: boolean = false
type Options = {
indexToInsertAt?: number
skipStepsCount?: number
}
export let getSteps: (driver: Driver, options?: Options | undefined) => DriveStep[] = () => []
let totalSteps = 0
let tutorial: Driver | undefined = undefined
const dispatch = createEventDispatcher()
// Render controls needs to be exposed so steps that have a custom render can call it
export function renderControls({ config, state }) {
const popoverDescription = document.querySelector('#driver-popover-description')
if (!tutorial) {
return
}
if (state.activeIndex == 0) {
const div = document.createElement('div')
mount(SkipTutorials, {
target: div,
events: {
skipAll: () => {
dispatch('skipAll')
tutorial?.destroy()
},
skipThis: () => {
updateProgress(index)
tutorial?.destroy()
}
}
})
if (popoverDescription) {
popoverDescription.appendChild(div)
}
}
const controls = document.createElement('div')
mount(TutorialControls, {
target: controls,
props: {
activeIndex: state.activeIndex,
totalSteps
},
events: {
next: () => {
const step = tutorial?.getActiveStep()
if (step) {
if (tutorial?.getActiveStep()?.popover?.onNextClick) {
const activeElement = tutorial?.getActiveElement()
tutorial?.getActiveStep()?.popover?.onNextClick?.(activeElement, step, {
config,
state,
driver: tutorial
})
} else {
tutorial?.moveNext()
}
}
},
previous: () => {
const step = tutorial?.getActiveStep()
if (step) {
if (tutorial?.getActiveStep()?.popover?.onPrevClick) {
const activeElement = tutorial?.getActiveElement()
tutorial?.getActiveStep()?.popover?.onPrevClick?.(activeElement, step, {
config,
state,
driver: tutorial
})
} else {
tutorial?.movePrevious()
}
}
}
}
})
if (popoverDescription) {
popoverDescription.appendChild(controls)
}
}
export const runTutorial = (options?: Options | undefined) => {
if (tainted) {
dispatch('error', { detail: name })
return
}
tutorial = driver({
allowClose: true,
disableActiveInteraction: true,
showButtons: ['close'],
showProgress: false,
overlayColor: 'rgba(0, 0, 0, 0.8)',
onPopoverRender: (popover, { config, state }) => {
renderControls({ config, state })
},
onDestroyed: () => {
if (!tutorial?.hasNextStep()) {
$ignoredTutorials = Array.from(new Set([...$ignoredTutorials, index]))
}
}
})
const steps = getSteps(tutorial, options)
totalSteps = steps.length
tutorial.setSteps(steps)
tutorial.drive()
}
</script>
<style>
:global(.driver-popover) {
padding: 32px;
}
:global(.driver-popover-title) {
font-size: 1.2rem !important;
line-height: 2 !important;
}
</style>