mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-06 00:02:13 +00:00
Deletes the guided-tour feature: the tutorials directory, the per-editor wrappers, the home banner and button, the /tutorials route, and the driver.js dependency they were built on. Also removes what only existed to serve them — the `tutorialsToDo` / `skippedAll` / `isCurrentlyInTutorial` stores, the `disableTutorials` prop chain through the flow editor, the `?tutorial=` deep links, PopupV2's clickOutside exemption for the driver popover, and the selector-anchor class on the flow editor tabs. The backend `tutorial_progress` endpoints and table stay: nothing calls them now, and removing them is a public-API break plus a migration that would drop existing progress. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012fRjnaHLwjpHN84gNNxah9
160 lines
4.7 KiB
Svelte
160 lines
4.7 KiB
Svelte
<script lang="ts">
|
|
import type { FlowEditorContext } from '../types'
|
|
import type { FlowDiffManager } from '../flowDiffManager.svelte'
|
|
import { createEventDispatcher, getContext } from 'svelte'
|
|
import { Bug, X } from 'lucide-svelte'
|
|
import InsertModulePopover from '$lib/components/flows/map/InsertModulePopover.svelte'
|
|
import { insertNewFailureModule } from '$lib/components/flows/flowStateUtils.svelte'
|
|
import type { RawScript, ScriptLang } from '$lib/gen'
|
|
import { twMerge } from 'tailwind-merge'
|
|
import { refreshFlowStateStore } from '$lib/components/flows/flowStoreRefresh.svelte'
|
|
import Button from '$lib/components/common/button/Button.svelte'
|
|
import DiffActionBar from './DiffActionBar.svelte'
|
|
import { getNodeColorClasses, aiActionToNodeState } from '$lib/components/graph'
|
|
|
|
let {
|
|
disableAi,
|
|
small,
|
|
diffManager,
|
|
compact = false
|
|
}: {
|
|
small: boolean
|
|
disableAi?: boolean
|
|
diffManager?: FlowDiffManager
|
|
compact?: boolean
|
|
} = $props()
|
|
|
|
const dispatch = createEventDispatcher<{
|
|
generateStep: { moduleId: string; instructions: string; lang: ScriptLang }
|
|
}>()
|
|
|
|
const { selectionManager, flowStateStore, flowStore, opWorkspace } =
|
|
getContext<FlowEditorContext>('FlowEditorContext')
|
|
|
|
const failureModuleId = $derived(flowStore.val?.value?.failure_module?.id)
|
|
const moduleAction = $derived(
|
|
failureModuleId ? diffManager?.moduleActions?.[failureModuleId] : undefined
|
|
)
|
|
const aiColorClasses = $derived(
|
|
moduleAction ? getNodeColorClasses(aiActionToNodeState(moduleAction.action), false) : undefined
|
|
)
|
|
|
|
async function insertFailureModule(
|
|
inlineScript?: {
|
|
language: RawScript['language']
|
|
subkind: 'pgsql' | 'flow'
|
|
instructions?: string
|
|
},
|
|
wsScript?: { path: string; summary: string; hash: string | undefined }
|
|
) {
|
|
await insertNewFailureModule(flowStore, flowStateStore, inlineScript, wsScript, opWorkspace?.())
|
|
|
|
if (inlineScript?.instructions) {
|
|
dispatch('generateStep', {
|
|
moduleId: 'failure',
|
|
instructions: inlineScript.instructions,
|
|
lang: inlineScript.language
|
|
})
|
|
}
|
|
|
|
selectionManager.selectId('failure')
|
|
refreshFlowStateStore(flowStore)
|
|
}
|
|
|
|
function deleteFailureModule() {
|
|
flowStore.val.value.failure_module = undefined
|
|
// The panel has to land somewhere once the error handler is gone, but that is a
|
|
// consequence of the delete — not a request to see the flow's settings.
|
|
selectionManager.selectId('settings-metadata', { openPanel: false })
|
|
}
|
|
|
|
const smallFailureModule = $derived(!(failureModuleId && diffManager && moduleAction) && compact)
|
|
</script>
|
|
|
|
{#if flowStore.val?.value?.failure_module}
|
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
<div class="relative">
|
|
<Button
|
|
variant="default"
|
|
unifiedSize="sm"
|
|
wrapperClasses={compact ? undefined : twMerge('min-w-36', small ? 'max-w-52' : 'max-w-64')}
|
|
id="flow-editor-error-handler"
|
|
selected={selectionManager.getSelectedId()?.includes('failure')}
|
|
onClick={() => {
|
|
if (flowStore.val?.value?.failure_module) {
|
|
selectionManager.selectId('failure')
|
|
}
|
|
}}
|
|
btnClasses={aiColorClasses?.bg ?? ''}
|
|
>
|
|
{#if failureModuleId}
|
|
<DiffActionBar
|
|
moduleId={failureModuleId}
|
|
{moduleAction}
|
|
{diffManager}
|
|
{flowStore}
|
|
placement="bottom"
|
|
/>
|
|
{/if}
|
|
<Bug size={14} class="shrink-0" />
|
|
{#if !smallFailureModule}
|
|
<div class="truncate grow min-w-0 text-center text-xs">
|
|
{flowStore.val.value.failure_module?.summary ||
|
|
(flowStore.val.value.failure_module?.value.type === 'rawscript'
|
|
? `${flowStore.val.value.failure_module?.value.language}`
|
|
: 'TBD')}
|
|
</div>
|
|
|
|
<button
|
|
title="Delete failure script"
|
|
type="button"
|
|
class="ml-1"
|
|
onclick={deleteFailureModule}
|
|
>
|
|
<X size={12} />
|
|
</button>
|
|
{/if}
|
|
</Button>
|
|
{#if smallFailureModule}
|
|
<button
|
|
title="Delete failure script"
|
|
type="button"
|
|
class="absolute -top-1.5 -right-1.5 rounded-full bg-surface border border-border p-0.5 hover:bg-surface-hover"
|
|
onclick={deleteFailureModule}
|
|
>
|
|
<X size={10} />
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
{:else}
|
|
<InsertModulePopover
|
|
{disableAi}
|
|
placement={'bottom'}
|
|
on:new={(e) => {
|
|
insertFailureModule(e.detail.inlineScript)
|
|
}}
|
|
on:pickScript={(e) => {
|
|
insertFailureModule(undefined, e.detail)
|
|
}}
|
|
kind="failure"
|
|
>
|
|
{#snippet trigger()}
|
|
<Button
|
|
unifiedSize="sm"
|
|
wrapperClasses={compact ? undefined : 'min-w-36'}
|
|
title={`Add failure module`}
|
|
variant="default"
|
|
id={`flow-editor-add-step-error-handler-button`}
|
|
nonCaptureEvent
|
|
startIcon={{ icon: Bug }}
|
|
iconOnly={compact}
|
|
>
|
|
{#if !compact}
|
|
Error Handler
|
|
{/if}
|
|
</Button>
|
|
{/snippet}
|
|
</InsertModulePopover>
|
|
{/if}
|