faet(frontend): Add tour manager store
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte'
|
||||
import Shepherd from 'shepherd.js'
|
||||
import { steps, type TutorialName } from './'
|
||||
import { steps, tourStore, type TutorialName } from './'
|
||||
|
||||
export let tutorial: TutorialName
|
||||
/**
|
||||
@@ -13,7 +12,12 @@
|
||||
}
|
||||
let tour: Shepherd.Tour | undefined
|
||||
|
||||
onMount(() => {
|
||||
$: $tourStore.includes(tutorial) && initiate()
|
||||
|
||||
function initiate() {
|
||||
if (!tourStore.isTourActive(tutorial)) {
|
||||
return
|
||||
}
|
||||
tour?.cancel()
|
||||
tour = new Shepherd.Tour({
|
||||
tourName: tutorial,
|
||||
@@ -42,8 +46,13 @@
|
||||
}
|
||||
})
|
||||
})
|
||||
;['complete', 'cancel'].forEach((event) => {
|
||||
tour?.on(event, () => {
|
||||
tourStore.markTourAsDone(tutorial)
|
||||
})
|
||||
})
|
||||
tour.start()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style global>
|
||||
|
||||
@@ -1,15 +1,51 @@
|
||||
import { browser } from '$app/environment'
|
||||
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'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
export { default as Tour } from './Tour.svelte'
|
||||
|
||||
export type TutorialName = 'welcome' | 'script' | 'flow' | 'app'
|
||||
export const TUTORIAL_NAMES = ['welcome', 'script', 'flow', 'app'] as const
|
||||
export type TutorialName = (typeof TUTORIAL_NAMES)[number]
|
||||
|
||||
export const steps: Record<TutorialName, (tour: Shepherd.Tour) => object[] | Shepherd.Step[]> = {
|
||||
welcome,
|
||||
script,
|
||||
flow,
|
||||
app
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'tutorials-to-show' as const
|
||||
const store = writable<Readonly<TutorialName[]>>([])
|
||||
export const tourStore = {
|
||||
subscribe: store.subscribe,
|
||||
initiateTours: () => {
|
||||
if (!browser) {
|
||||
return
|
||||
}
|
||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(TUTORIAL_NAMES))
|
||||
store.set(TUTORIAL_NAMES)
|
||||
},
|
||||
isTourActive: (name: TutorialName) => {
|
||||
if (!browser) {
|
||||
return false
|
||||
}
|
||||
const toursToShow = JSON.parse(
|
||||
window.localStorage.getItem(STORAGE_KEY) || '[]'
|
||||
) as TutorialName[]
|
||||
return toursToShow.includes(name)
|
||||
},
|
||||
markTourAsDone: (name: TutorialName) => {
|
||||
if (!browser) {
|
||||
return
|
||||
}
|
||||
const toursToShow = (
|
||||
JSON.parse(window.localStorage.getItem(STORAGE_KEY) || '[]') as TutorialName[]
|
||||
).filter((t) => t !== name)
|
||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(toursToShow))
|
||||
store.set(toursToShow)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
import AppPreview from '$lib/components/apps/editor/AppPreview.svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
import type { EditorBreakpoint } from '$lib/components/apps/types'
|
||||
import { Tour } from '../../../lib/components/tutorial'
|
||||
import { Tour, tourStore } from '../../../lib/components/tutorial'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
type Tab = 'hubscripts' | 'hubflows' | 'hubapps' | 'workspace'
|
||||
|
||||
@@ -61,9 +62,12 @@
|
||||
appViewerApp = hub
|
||||
appViewer.openDrawer?.()
|
||||
}
|
||||
|
||||
onMount(tourStore.initiateTours)
|
||||
</script>
|
||||
|
||||
<Tour tutorial="welcome" />
|
||||
|
||||
<Drawer bind:this={codeViewer} size="900px">
|
||||
<DrawerContent title={codeViewerObj?.summary ?? ''} on:close={codeViewer.closeDrawer}>
|
||||
<svelte:fragment slot="actions">
|
||||
|
||||
Reference in New Issue
Block a user