Tutorials improvement (#2384)
* fix(frontend): fix tutorials * fix(frontend): simplify * fix(frontend): simplify * fix(frontend): fix skip all * fix(frontend): fix toggle * fix(frontend): simplify
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
copilotInfo,
|
||||
enterpriseLicense,
|
||||
hubScripts,
|
||||
tutorialsToDo,
|
||||
userStore,
|
||||
workspaceStore
|
||||
} from '$lib/stores'
|
||||
@@ -56,6 +57,9 @@
|
||||
import FlowCopilotInputsModal from './copilot/FlowCopilotInputsModal.svelte'
|
||||
import FlowBuilderTutorials from './FlowBuilderTutorials.svelte'
|
||||
|
||||
import FlowTutorials from './FlowTutorials.svelte'
|
||||
import { tainted } from './tutorials/utils'
|
||||
|
||||
export let initialPath: string = ''
|
||||
export let selectedId: string | undefined
|
||||
export let initialArgs: Record<string, any> = {}
|
||||
@@ -847,6 +851,18 @@
|
||||
$: $copilotCurrentStepStore === undefined && blurCopilot()
|
||||
|
||||
let renderCount = 0
|
||||
let flowTutorials: FlowTutorials | undefined = undefined
|
||||
|
||||
$: if (!tainted($flowStore) && loading === false) {
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
const tutorial = urlParams.get('tutorial')
|
||||
|
||||
if (tutorial) {
|
||||
flowTutorials?.runTutorialById(tutorial)
|
||||
} else if ($tutorialsToDo.includes(0)) {
|
||||
flowTutorials?.runTutorialById('action')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
@@ -983,7 +999,12 @@
|
||||
|
||||
<!-- metadata -->
|
||||
{#if $flowStateStore}
|
||||
<FlowEditor {loading} />
|
||||
<FlowEditor
|
||||
{loading}
|
||||
on:reload={() => {
|
||||
renderCount += 1
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<CenteredPage>Loading...</CenteredPage>
|
||||
{/if}
|
||||
@@ -992,3 +1013,10 @@
|
||||
Flow Builder not available to operators
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
<FlowTutorials
|
||||
bind:this={flowTutorials}
|
||||
on:reload={() => {
|
||||
renderCount += 1
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -3,81 +3,110 @@
|
||||
import ButtonDropdown from './common/button/ButtonDropdown.svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
|
||||
import FlowBuilderTutorialSimpleFlow from './tutorials/FlowBuilderTutorialSimpleFlow.svelte'
|
||||
import FlowBuilderTutorialsForLoop from './tutorials/FlowBuilderTutorialsForLoop.svelte'
|
||||
import FlowBranchOne from './tutorials/FlowBranchOne.svelte'
|
||||
import FlowBranchAll from './tutorials/FlowBranchAll.svelte'
|
||||
import MenuItem from './common/menu/MenuItem.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { resetAllTodos, skipAllTodos } from '$lib/tutorialUtils'
|
||||
import { tutorialsToDo } from '$lib/stores'
|
||||
import { getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from './flows/types'
|
||||
import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte'
|
||||
import TutorialItem from './tutorials/TutorialItem.svelte'
|
||||
import FlowTutorials from './FlowTutorials.svelte'
|
||||
|
||||
const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
let flowBuilderTutorialSimpleFlow: FlowBuilderTutorialSimpleFlow | undefined = undefined
|
||||
|
||||
$: tainted =
|
||||
$flowStore.value.modules.length > 0 || Object.keys($flowStore?.schema?.properties).length > 0
|
||||
|
||||
let automaticallyRan: boolean = false
|
||||
|
||||
$: if (!automaticallyRan && $tutorialsToDo.includes(0)) {
|
||||
automaticallyRan = true
|
||||
flowBuilderTutorialSimpleFlow?.runTutorial()
|
||||
}
|
||||
let targetTutorial: string | undefined = undefined
|
||||
let flowTutorials: FlowTutorials | undefined = undefined
|
||||
</script>
|
||||
|
||||
{#if !tainted}
|
||||
<button on:pointerdown|stopPropagation>
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button nonCaptureEvent size="xs" color="light" variant="border" id="tutorials-button">
|
||||
<div class="flex flex-row gap-2 items-center">
|
||||
<BookOpen size={16} />
|
||||
Tutorials
|
||||
</div>
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
<FlowBuilderTutorialSimpleFlow on:reload on:skipAll={skipAllTodos} />
|
||||
<FlowBuilderTutorialsForLoop on:reload on:skipAll={skipAllTodos} />
|
||||
<FlowBranchOne on:reload on:skipAll={skipAllTodos} />
|
||||
<FlowBranchAll on:reload on:skipAll={skipAllTodos} />
|
||||
<div class="border-t border-surface-hover" />
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
resetAllTodos()
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'text-primary flex flex-row items-center text-left gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
Reset tutorials
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem on:click={() => skipAllTodos()}>
|
||||
<div
|
||||
class={classNames(
|
||||
'text-primary flex flex-row items-center text-left gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
Skip tutorials
|
||||
</div>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
{/if}
|
||||
<button on:pointerdown|stopPropagation>
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button nonCaptureEvent size="xs" color="light" variant="border" id="tutorials-button">
|
||||
<div class="flex flex-row gap-2 items-center">
|
||||
<BookOpen size={16} />
|
||||
Tutorials
|
||||
</div>
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('action')}
|
||||
label="Simple flow tutorial"
|
||||
index={0}
|
||||
id="flow-builder-tutorial-action"
|
||||
/>
|
||||
|
||||
<FlowBuilderTutorialSimpleFlow
|
||||
bind:this={flowBuilderTutorialSimpleFlow}
|
||||
shouldRenderButton={false}
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('forloop')}
|
||||
label="For loops tutorial"
|
||||
index={1}
|
||||
id="flow-builder-tutorial-forloops"
|
||||
/>
|
||||
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('branchone')}
|
||||
label="Branch one tutorial"
|
||||
index={2}
|
||||
id="flow-builder-tutorial-branchone"
|
||||
/>
|
||||
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('branchall')}
|
||||
label="Branch all tutorial"
|
||||
index={3}
|
||||
id="flow-builder-tutorial-branchall"
|
||||
/>
|
||||
|
||||
<div class="border-t border-surface-hover" />
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
resetAllTodos()
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'text-primary flex flex-row items-center text-left gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
Reset tutorials
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem on:click={() => skipAllTodos()}>
|
||||
<div
|
||||
class={classNames(
|
||||
'text-primary flex flex-row items-center text-left gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
Skip tutorials
|
||||
</div>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
|
||||
<FlowTutorials
|
||||
bind:this={flowTutorials}
|
||||
on:error={({ detail }) => {
|
||||
targetTutorial = detail.detail
|
||||
}}
|
||||
on:skipAll={() => {
|
||||
skipAllTodos()
|
||||
}}
|
||||
on:reload
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
open={targetTutorial !== undefined}
|
||||
title="Tutorial error"
|
||||
confirmationText="Open new tab"
|
||||
on:canceled={() => {
|
||||
targetTutorial = undefined
|
||||
}}
|
||||
on:confirmed={async () => {
|
||||
window.open(`/flows/add?tutorial=${targetTutorial}&nodraft=true`, '_blank')
|
||||
}}
|
||||
>
|
||||
<div class="flex flex-col w-full space-y-4">
|
||||
<span> You need to create a new flow before starting the tutorial.</span>
|
||||
</div>
|
||||
</ConfirmationModal>
|
||||
|
||||
<style global>
|
||||
.driver-popover-title {
|
||||
@apply leading-6 text-primary text-base;
|
||||
|
||||
44
frontend/src/lib/components/FlowTutorials.svelte
Normal file
44
frontend/src/lib/components/FlowTutorials.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import { skipAllTodos } from '$lib/tutorialUtils'
|
||||
import FlowBranchAll from './tutorials/FlowBranchAll.svelte'
|
||||
import FlowBranchOne from './tutorials/FlowBranchOne.svelte'
|
||||
import FlowBuilderTutorialSimpleFlow from './tutorials/FlowBuilderTutorialSimpleFlow.svelte'
|
||||
import FlowBuilderTutorialsForLoop from './tutorials/FlowBuilderTutorialsForLoop.svelte'
|
||||
|
||||
let flowBuilderTutorialSimpleFlow: FlowBuilderTutorialSimpleFlow | undefined = undefined
|
||||
let flowBuilderTutorialsForLoop: FlowBuilderTutorialsForLoop | undefined = undefined
|
||||
let flowBranchOne: FlowBranchOne | undefined = undefined
|
||||
let flowBranchAll: FlowBranchAll | undefined = undefined
|
||||
|
||||
export function runTutorialById(id: string) {
|
||||
console.log(id, flowBranchOne)
|
||||
if (id === 'forloop') {
|
||||
flowBuilderTutorialsForLoop?.runTutorial()
|
||||
} else if (id === 'branchone') {
|
||||
flowBranchOne?.runTutorial()
|
||||
} else if (id === 'branchall') {
|
||||
flowBranchAll?.runTutorial()
|
||||
} else if (id === 'action') {
|
||||
flowBuilderTutorialSimpleFlow?.runTutorial()
|
||||
}
|
||||
}
|
||||
|
||||
function skipAll() {
|
||||
skipAllTodos()
|
||||
}
|
||||
</script>
|
||||
|
||||
<FlowBuilderTutorialSimpleFlow
|
||||
bind:this={flowBuilderTutorialSimpleFlow}
|
||||
on:error
|
||||
on:skipAll={skipAll}
|
||||
on:reload
|
||||
/>
|
||||
<FlowBuilderTutorialsForLoop
|
||||
bind:this={flowBuilderTutorialsForLoop}
|
||||
on:error
|
||||
on:skipAll={skipAll}
|
||||
on:reload
|
||||
/>
|
||||
<FlowBranchOne bind:this={flowBranchOne} on:error on:skipAll={skipAll} on:reload />
|
||||
<FlowBranchAll bind:this={flowBranchAll} on:error on:skipAll={skipAll} on:reload />
|
||||
@@ -35,7 +35,7 @@
|
||||
{/each}
|
||||
</div>
|
||||
{:else if $flowStore.value.modules}
|
||||
<FlowModuleSchemaMap bind:modules={$flowStore.value.modules} />
|
||||
<FlowModuleSchemaMap bind:modules={$flowStore.value.modules} on:reload />
|
||||
{/if}
|
||||
</div>
|
||||
</Pane>
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
</Slider>
|
||||
</div>
|
||||
</TabContent>
|
||||
<TabContent value="settings-schedule" class="p-4">
|
||||
<TabContent value="settings-schedule" class="p-4 h-full overflow-scroll">
|
||||
<Alert
|
||||
type="info"
|
||||
title="Primary Schedule"
|
||||
|
||||
@@ -23,16 +23,14 @@
|
||||
import type { FlowCopilotContext } from '$lib/components/copilot/flow'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { tutorialsToDo } from '$lib/stores'
|
||||
import FlowBuilderTutorialsForLoop from '$lib/components/tutorials/FlowBuilderTutorialsForLoop.svelte'
|
||||
import FlowBranchOne from '$lib/components/tutorials/FlowBranchOne.svelte'
|
||||
import FlowBranchAll from '$lib/components/tutorials/FlowBranchAll.svelte'
|
||||
|
||||
import FlowTutorials from '$lib/components/FlowTutorials.svelte'
|
||||
import { tainted } from '$lib/components/tutorials/utils'
|
||||
|
||||
export let modules: FlowModule[] | undefined
|
||||
export let sidebarSize: number | undefined = undefined
|
||||
|
||||
let flowBuilderTutorialsForLoop: FlowBuilderTutorialsForLoop | undefined = undefined
|
||||
let flowBranchOne: FlowBranchOne | undefined = undefined
|
||||
let flowBranchAll: FlowBranchAll | undefined = undefined
|
||||
let flowTutorials: FlowTutorials | undefined = undefined
|
||||
|
||||
const { selectedId, moving, history, flowStateStore, flowStore } =
|
||||
getContext<FlowEditorContext>('FlowEditorContext')
|
||||
@@ -214,12 +212,29 @@
|
||||
}
|
||||
}}
|
||||
on:insert={async ({ detail }) => {
|
||||
if ($tutorialsToDo.includes(1) && detail.detail == 'forloop') {
|
||||
flowBuilderTutorialsForLoop?.runTutorial()
|
||||
} else if ($tutorialsToDo.includes(2) && detail.detail == 'branchone') {
|
||||
flowBranchOne?.runTutorial()
|
||||
} else if ($tutorialsToDo.includes(3) && detail.detail == 'branchall') {
|
||||
flowBranchAll?.runTutorial()
|
||||
const svg = document.getElementsByClassName('driver-overlay driver-overlay-animated')
|
||||
const isTainted = tainted($flowStore)
|
||||
if (
|
||||
$tutorialsToDo.includes(1) &&
|
||||
detail.detail == 'forloop' &&
|
||||
svg.length === 0 &&
|
||||
!isTainted
|
||||
) {
|
||||
flowTutorials?.runTutorialById('forloop')
|
||||
} else if (
|
||||
$tutorialsToDo.includes(2) &&
|
||||
detail.detail == 'branchone' &&
|
||||
svg.length === 0 &&
|
||||
!isTainted
|
||||
) {
|
||||
flowTutorials?.runTutorialById('branchone')
|
||||
} else if (
|
||||
$tutorialsToDo.includes(3) &&
|
||||
detail.detail == 'branchall' &&
|
||||
svg.length === 0 &&
|
||||
!isTainted
|
||||
) {
|
||||
flowTutorials?.runTutorialById('branchall')
|
||||
} else {
|
||||
if (detail.modules) {
|
||||
await tick()
|
||||
@@ -270,6 +285,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FlowBuilderTutorialsForLoop bind:this={flowBuilderTutorialsForLoop} shouldRenderButton={false} />
|
||||
<FlowBranchOne bind:this={flowBranchOne} shouldRenderButton={false} />
|
||||
<FlowBranchAll bind:this={flowBranchAll} shouldRenderButton={false} />
|
||||
<FlowTutorials bind:this={flowTutorials} on:reload />
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
import 'driver.js/dist/driver.css'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../flows/types'
|
||||
import TutorialItem from './TutorialItem.svelte'
|
||||
import { clickButtonBySelector, triggerAddFlowStep, selectFlowStepKind } from './utils'
|
||||
import { clickButtonBySelector, triggerAddFlowStep, selectFlowStepKind, tainted } from './utils'
|
||||
import { updateProgress } from '$lib/tutorialUtils'
|
||||
import { RawScript } from '$lib/gen'
|
||||
|
||||
export let shouldRenderButton: boolean = true
|
||||
|
||||
const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export function runTutorial() {
|
||||
if (tainted($flowStore)) {
|
||||
dispatch('error', { detail: 'branchall' })
|
||||
return
|
||||
}
|
||||
|
||||
const branchAllTutorial = driver({
|
||||
showProgress: true,
|
||||
allowClose: true,
|
||||
@@ -96,6 +98,7 @@
|
||||
description: "Let's pick branch all",
|
||||
onNextClick: () => {
|
||||
selectFlowStepKind(6)
|
||||
|
||||
setTimeout(() => {
|
||||
branchAllTutorial.moveNext()
|
||||
})
|
||||
@@ -216,12 +219,3 @@
|
||||
branchAllTutorial.drive()
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRenderButton}
|
||||
<TutorialItem
|
||||
on:click={() => runTutorial()}
|
||||
label="Branch all tutorial"
|
||||
index={3}
|
||||
id="flow-builder-tutorial-branchall"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -3,22 +3,25 @@
|
||||
import 'driver.js/dist/driver.css'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../flows/types'
|
||||
import TutorialItem from './TutorialItem.svelte'
|
||||
import {
|
||||
clickButtonBySelector,
|
||||
setInputBySelector,
|
||||
triggerAddFlowStep,
|
||||
selectFlowStepKind
|
||||
selectFlowStepKind,
|
||||
tainted
|
||||
} from './utils'
|
||||
import { updateProgress } from '$lib/tutorialUtils'
|
||||
import { RawScript } from '$lib/gen'
|
||||
|
||||
export let shouldRenderButton: boolean = true
|
||||
|
||||
const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export function runTutorial() {
|
||||
if (tainted($flowStore)) {
|
||||
dispatch('error', { detail: 'branchone' })
|
||||
return
|
||||
}
|
||||
|
||||
const branchOneTutorial = driver({
|
||||
showProgress: true,
|
||||
allowClose: true,
|
||||
@@ -308,12 +311,3 @@
|
||||
branchOneTutorial.drive()
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRenderButton}
|
||||
<TutorialItem
|
||||
on:click={() => runTutorial()}
|
||||
label="Branch one tutorial"
|
||||
index={2}
|
||||
id="flow-builder-tutorial-branchone"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { driver } from 'driver.js'
|
||||
import 'driver.js/dist/driver.css'
|
||||
import { createEventDispatcher, getContext, tick } from 'svelte'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../flows/types'
|
||||
import { updateProgress } from '$lib/tutorialUtils'
|
||||
import TutorialItem from './TutorialItem.svelte'
|
||||
import {
|
||||
clickButtonBySelector,
|
||||
selectFlowStepKind,
|
||||
setInputBySelector,
|
||||
tainted,
|
||||
triggerAddFlowStep
|
||||
} from './utils'
|
||||
|
||||
export let shouldRenderButton: boolean = true
|
||||
|
||||
const { flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const queue: string[] = []
|
||||
|
||||
export function runTutorial() {
|
||||
if (tainted($flowStore)) {
|
||||
dispatch('error', { detail: 'action' })
|
||||
return
|
||||
}
|
||||
|
||||
const simpleFlowTutorial = driver({
|
||||
showProgress: true,
|
||||
allowClose: true,
|
||||
@@ -247,7 +250,7 @@
|
||||
$flowStore = $flowStore
|
||||
dispatch('reload')
|
||||
|
||||
tick().then(() => {
|
||||
setTimeout(() => {
|
||||
simpleFlowTutorial.moveNext()
|
||||
})
|
||||
}
|
||||
@@ -312,12 +315,3 @@
|
||||
simpleFlowTutorial.drive()
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRenderButton}
|
||||
<TutorialItem
|
||||
on:click={() => runTutorial()}
|
||||
label="Simple flow tutorial"
|
||||
index={0}
|
||||
id="flow-builder-tutorial-action"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -3,25 +3,28 @@
|
||||
import 'driver.js/dist/driver.css'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../flows/types'
|
||||
import TutorialItem from './TutorialItem.svelte'
|
||||
import { emptyFlowModuleState } from '../flows/utils'
|
||||
import {
|
||||
clickButtonBySelector,
|
||||
setInputBySelector,
|
||||
triggerAddFlowStep,
|
||||
selectFlowStepKind,
|
||||
selectOptionsBySelector
|
||||
selectOptionsBySelector,
|
||||
tainted
|
||||
} from './utils'
|
||||
import { updateProgress } from '$lib/tutorialUtils'
|
||||
|
||||
export let shouldRenderButton: boolean = true
|
||||
|
||||
const { flowStore, selectedId, flowStateStore } =
|
||||
getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export function runTutorial() {
|
||||
if (tainted($flowStore)) {
|
||||
dispatch('error', { detail: 'forloop' })
|
||||
return
|
||||
}
|
||||
|
||||
const forloopTutorial = driver({
|
||||
showProgress: true,
|
||||
allowClose: true,
|
||||
@@ -405,12 +408,3 @@
|
||||
forloopTutorial.drive()
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if shouldRenderButton}
|
||||
<TutorialItem
|
||||
on:click={() => runTutorial()}
|
||||
label="For loops tutorial"
|
||||
index={1}
|
||||
id="flow-builder-tutorial-forloops"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -7,21 +7,24 @@
|
||||
|
||||
export let label: string
|
||||
export let index: number
|
||||
export let shouldRenderButton: boolean = true
|
||||
export let id: string
|
||||
</script>
|
||||
|
||||
<MenuItem on:click>
|
||||
<div
|
||||
{id}
|
||||
class={classNames(
|
||||
'text-primary flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{#if $tutorialsToDo.includes(index)}
|
||||
<Circle size={16} />
|
||||
{:else}
|
||||
<CheckCircle size={16} color="green" />
|
||||
{/if}
|
||||
{label}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{#if shouldRenderButton}
|
||||
<MenuItem on:click>
|
||||
<div
|
||||
{id}
|
||||
class={classNames(
|
||||
'text-primary flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{#if $tutorialsToDo.includes(index)}
|
||||
<Circle size={16} />
|
||||
{:else}
|
||||
<CheckCircle size={16} color="green" />
|
||||
{/if}
|
||||
{label}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/if}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { Flow } from '$lib/gen'
|
||||
|
||||
export function setInputBySelector(selector: string, value: string) {
|
||||
const input = document.querySelector(selector) as HTMLInputElement
|
||||
|
||||
@@ -41,3 +43,7 @@ export function selectOptionsBySelector(selector: string, value: string) {
|
||||
select.dispatchEvent(new Event('change', { bubbles: true }))
|
||||
}
|
||||
}
|
||||
|
||||
export function tainted(flow: Flow) {
|
||||
return flow.value.modules.length > 0 || Object.keys(flow?.schema?.properties).length > 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user