mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-05 08:02:18 +00:00
replace ButtonDropdown with DropdownV2
This commit is contained in:
@@ -3,23 +3,14 @@
|
||||
import { Menu, Menubar } from '$lib/components/meltComponents'
|
||||
import { melt } from '@melt-ui/svelte'
|
||||
import type { Placement } from '@floating-ui/core'
|
||||
|
||||
import type { Item } from '$lib/utils'
|
||||
import DropdownV2Inner from './DropdownV2Inner.svelte'
|
||||
|
||||
type Item = {
|
||||
displayName: string
|
||||
action?: (e: CustomEvent<any>) => void
|
||||
icon?: any
|
||||
href?: string
|
||||
disabled?: boolean
|
||||
type?: 'action' | 'delete'
|
||||
hide?: boolean | undefined
|
||||
}
|
||||
|
||||
export let items: Item[] | (() => Item[]) | (() => Promise<Item[]>) = []
|
||||
export let justifyEnd: boolean = true
|
||||
export let disabled = false
|
||||
export let placement: Placement = 'bottom-end'
|
||||
export let usePointerDownOutside = false
|
||||
|
||||
async function computeItems(): Promise<Item[]> {
|
||||
if (typeof items === 'function') {
|
||||
@@ -31,7 +22,17 @@
|
||||
</script>
|
||||
|
||||
<Menubar let:createMenu>
|
||||
<Menu {createMenu} {placement} {justifyEnd} on:close on:open {disabled} let:item>
|
||||
<Menu
|
||||
{createMenu}
|
||||
{placement}
|
||||
{justifyEnd}
|
||||
on:close
|
||||
on:open
|
||||
{disabled}
|
||||
let:item
|
||||
class={$$props.class}
|
||||
{usePointerDownOutside}
|
||||
>
|
||||
<svelte:fragment slot="trigger" let:trigger>
|
||||
<div use:melt={trigger}>
|
||||
{#if $$slots.buttonReplacement}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
displayName: string
|
||||
action?: (e: CustomEvent<any>) => void
|
||||
icon?: any
|
||||
iconColor?: string
|
||||
href?: string
|
||||
disabled?: boolean
|
||||
type?: 'action' | 'delete'
|
||||
@@ -36,7 +37,7 @@
|
||||
href={item?.href}
|
||||
disabled={item?.disabled}
|
||||
class={twMerge(
|
||||
'px-4 py-2 text-primary font-normal hover:bg-surface-hover cursor-pointer text-xs transition-all',
|
||||
'px-4 py-2 text-primary font-semibold hover:bg-surface-hover cursor-pointer text-xs transition-all',
|
||||
'data-[highlighted]:bg-surface-hover',
|
||||
'flex flex-row gap-2 items-center',
|
||||
item?.disabled && 'text-gray-400 cursor-not-allowed',
|
||||
@@ -47,7 +48,7 @@
|
||||
item={meltItem}
|
||||
>
|
||||
{#if item.icon}
|
||||
<svelte:component this={item.icon} size={14} />
|
||||
<svelte:component this={item.icon} size={14} color={item.iconColor} />
|
||||
{/if}
|
||||
{item.displayName}
|
||||
</MenuItem>
|
||||
|
||||
@@ -73,14 +73,11 @@
|
||||
import { loadFlowModuleState, pickScript } from './flows/flowStateUtils'
|
||||
import FlowCopilotInputsModal from './copilot/FlowCopilotInputsModal.svelte'
|
||||
import FlowBuilderTutorials from './FlowBuilderTutorials.svelte'
|
||||
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import FlowTutorials from './FlowTutorials.svelte'
|
||||
import { ignoredTutorials } from './tutorials/ignoredTutorials'
|
||||
import type DiffDrawer from './DiffDrawer.svelte'
|
||||
import FlowHistory from './flows/FlowHistory.svelte'
|
||||
import ButtonDropdown from './common/button/ButtonDropdown.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import CustomPopover from './CustomPopover.svelte'
|
||||
import Summary from './Summary.svelte'
|
||||
import type { FlowBuilderWhitelabelCustomUi } from './custom_ui'
|
||||
@@ -1364,33 +1361,16 @@
|
||||
{/if}
|
||||
<div>
|
||||
{#if moreItems?.length > 0}
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<Dropdown items={moreItems} class="center-center">
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button nonCaptureEvent size="xs" color="light">
|
||||
<div class="flex flex-row items-center">
|
||||
<MoreVertical size={14} />
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
nonCaptureEvent
|
||||
size="xs"
|
||||
color="light"
|
||||
startIcon={{ icon: MoreVertical }}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
{#each moreItems as item}
|
||||
<MenuItem
|
||||
on:click={item.action}
|
||||
disabled={item.disabled}
|
||||
class={item.disabled ? 'opacity-50' : ''}
|
||||
>
|
||||
<div
|
||||
class={twMerge(
|
||||
'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'
|
||||
)}
|
||||
>
|
||||
<svelte:component this={item.icon} size={14} />
|
||||
{item.displayName}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/each}
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</Dropdown>
|
||||
{/if}
|
||||
</div>
|
||||
{#if customUi?.topBar?.tutorials != false}
|
||||
|
||||
@@ -1,21 +1,47 @@
|
||||
<script lang="ts">
|
||||
import { BookOpen } from 'lucide-svelte'
|
||||
import ButtonDropdown from './common/button/ButtonDropdown.svelte'
|
||||
import { BookOpen, CheckCircle, Circle, RefreshCw, CheckCheck } from 'lucide-svelte'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
|
||||
import MenuItem from './common/menu/MenuItem.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { resetAllTodos, skipAllTodos } from '$lib/tutorialUtils'
|
||||
import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte'
|
||||
import TutorialItem from './tutorials/TutorialItem.svelte'
|
||||
import FlowTutorials from './FlowTutorials.svelte'
|
||||
import { tutorialsToDo } from '$lib/stores'
|
||||
|
||||
let targetTutorial: string | undefined = undefined
|
||||
let flowTutorials: FlowTutorials | undefined = undefined
|
||||
|
||||
async function getTutorialItems() {
|
||||
const tutorials = [
|
||||
{ displayName: 'Simple flow tutorials', id: 'action' },
|
||||
{ displayName: 'For loops tutorial', id: 'forloop' },
|
||||
{ displayName: 'Branch one tutorial', id: 'branchone' },
|
||||
{ displayName: 'Branch all tutorial', id: 'branchall' },
|
||||
{ displayName: 'Error handler', id: 'error-handler' }
|
||||
]
|
||||
|
||||
return [
|
||||
...tutorials.map((tutorial, index) => ({
|
||||
displayName: tutorial.displayName,
|
||||
action: () => flowTutorials?.runTutorialById(tutorial.id),
|
||||
icon: $tutorialsToDo.includes(index) ? Circle : CheckCircle,
|
||||
iconColor: $tutorialsToDo.includes(index) ? undefined : 'green'
|
||||
})),
|
||||
{
|
||||
displayName: 'Skip tutorials',
|
||||
action: () => skipAllTodos(),
|
||||
icon: CheckCheck
|
||||
},
|
||||
{
|
||||
displayName: 'Reset tutorials',
|
||||
action: () => resetAllTodos(),
|
||||
icon: RefreshCw
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<button on:pointerdown|stopPropagation>
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
{#key $tutorialsToDo}
|
||||
<Dropdown items={getTutorialItems}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button
|
||||
nonCaptureEvent
|
||||
@@ -26,63 +52,8 @@
|
||||
startIcon={{ icon: BookOpen }}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('action')}
|
||||
label="Simple flow tutorial"
|
||||
index={0}
|
||||
/>
|
||||
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('forloop')}
|
||||
label="For loops tutorial"
|
||||
index={1}
|
||||
/>
|
||||
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('branchone')}
|
||||
label="Branch one tutorial"
|
||||
index={2}
|
||||
/>
|
||||
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('branchall')}
|
||||
label="Branch all tutorial"
|
||||
index={3}
|
||||
/>
|
||||
|
||||
<TutorialItem
|
||||
on:click={() => flowTutorials?.runTutorialById('error-handler')}
|
||||
label="Error handler"
|
||||
index={4}
|
||||
/>
|
||||
|
||||
<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>
|
||||
</Dropdown>
|
||||
{/key}
|
||||
|
||||
<FlowTutorials
|
||||
bind:this={flowTutorials}
|
||||
|
||||
@@ -69,8 +69,7 @@
|
||||
import DeploymentHistory from './DeploymentHistory.svelte'
|
||||
import Awareness from '$lib/components/Awareness.svelte'
|
||||
import { secondaryMenuLeftStore, secondaryMenuRightStore } from './settingsPanel/secondaryMenu'
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import AppEditorTutorial from './AppEditorTutorial.svelte'
|
||||
import AppTimeline from './AppTimeline.svelte'
|
||||
import type DiffDrawer from '$lib/components/DiffDrawer.svelte'
|
||||
@@ -1645,33 +1644,11 @@
|
||||
<Awareness />
|
||||
{/if}
|
||||
<div class="flex flex-row gap-2 justify-end items-center overflow-visible">
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<Dropdown items={moreItems} class="center-center">
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button nonCaptureEvent size="xs" color="light">
|
||||
<div class="flex flex-row items-center">
|
||||
<MoreVertical size={14} />
|
||||
</div>
|
||||
</Button>
|
||||
<Button nonCaptureEvent size="xs" color="light" startIcon={{ icon: MoreVertical }} />
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
{#each moreItems as item}
|
||||
<MenuItem
|
||||
on:click={item.action}
|
||||
disabled={item.disabled}
|
||||
class={item.disabled ? 'opacity-50' : ''}
|
||||
>
|
||||
<div
|
||||
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'
|
||||
)}
|
||||
>
|
||||
<svelte:component this={item.icon} size={14} />
|
||||
{item.displayName}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/each}
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</Dropdown>
|
||||
<AppEditorTutorial bind:this={appEditorTutorial} />
|
||||
|
||||
<div class="hidden md:inline relative overflow-visible">
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
<script lang="ts">
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import AppTutorials from '../../AppTutorials.svelte'
|
||||
import { BookOpen } from 'lucide-svelte'
|
||||
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import TutorialItem from '$lib/components/tutorials/TutorialItem.svelte'
|
||||
import MenuItem from '$lib/components/common/menu/MenuItem.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { BookOpen, CheckCircle, Circle, RefreshCw, CheckCheck } from 'lucide-svelte'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { resetAllTodos, skipAllTodos } from '$lib/tutorialUtils'
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import type { AppViewerContext } from '../types'
|
||||
@@ -45,63 +41,60 @@
|
||||
appTutorials?.runTutorialById('simpleapptutorial')
|
||||
}
|
||||
}
|
||||
|
||||
async function getTutorialItems() {
|
||||
return [
|
||||
{
|
||||
displayName: 'App tutorial',
|
||||
action: () => appTutorials?.runTutorialById('simpleapptutorial'),
|
||||
index: 7,
|
||||
icon: $tutorialsToDo.includes(7) ? Circle : CheckCircle,
|
||||
iconColor: $tutorialsToDo.includes(7) ? undefined : 'green'
|
||||
},
|
||||
{
|
||||
displayName: 'Background runnables',
|
||||
action: () => appTutorials?.runTutorialById('backgroundrunnables'),
|
||||
index: 5,
|
||||
icon: $tutorialsToDo.includes(5) ? Circle : CheckCircle,
|
||||
iconColor: $tutorialsToDo.includes(5) ? undefined : 'green'
|
||||
},
|
||||
{
|
||||
displayName: 'Connection',
|
||||
action: () => appTutorials?.runTutorialById('connection'),
|
||||
index: 6,
|
||||
icon: $tutorialsToDo.includes(6) ? Circle : CheckCircle,
|
||||
iconColor: $tutorialsToDo.includes(6) ? undefined : 'green'
|
||||
},
|
||||
{
|
||||
displayName: 'Reset tutorials',
|
||||
action: () => resetAllTodos(),
|
||||
icon: RefreshCw
|
||||
},
|
||||
{
|
||||
displayName: 'Skip tutorials',
|
||||
action: () => skipAllTodos(),
|
||||
icon: CheckCheck
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button
|
||||
nonCaptureEvent
|
||||
size="xs"
|
||||
color="light"
|
||||
variant="border"
|
||||
iconOnly
|
||||
startIcon={{
|
||||
icon: BookOpen
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
<TutorialItem
|
||||
on:click={() => appTutorials?.runTutorialById('simpleapptutorial')}
|
||||
label="App tutorial"
|
||||
index={7}
|
||||
/>
|
||||
<TutorialItem
|
||||
on:click={() => appTutorials?.runTutorialById('backgroundrunnables')}
|
||||
label="Background runnables"
|
||||
index={5}
|
||||
/>
|
||||
<TutorialItem
|
||||
on:click={() => appTutorials?.runTutorialById('connection')}
|
||||
label="Connection"
|
||||
index={6}
|
||||
/>
|
||||
|
||||
<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>
|
||||
{#key $tutorialsToDo}
|
||||
<Dropdown items={getTutorialItems} hasPadding={false}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button
|
||||
nonCaptureEvent
|
||||
size="xs"
|
||||
color="light"
|
||||
variant="border"
|
||||
iconOnly
|
||||
startIcon={{
|
||||
icon: BookOpen
|
||||
}}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</Dropdown>
|
||||
{/key}
|
||||
|
||||
<AppTutorials
|
||||
bind:this={appTutorials}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { AppViewerContext } from '../types'
|
||||
import type { DecisionTreeNode } from './component'
|
||||
@@ -69,81 +68,68 @@
|
||||
}
|
||||
|
||||
$: onNodesChange(nodes)
|
||||
|
||||
async function getDropdownItems() {
|
||||
return [
|
||||
// Debug node items
|
||||
...(nodes ?? []).map((node, index) => ({
|
||||
displayName: `Debug node ${node.label}`,
|
||||
action: () => {
|
||||
$componentControl?.[id]?.setTab?.(index)
|
||||
$debuggingComponents[id] = index
|
||||
},
|
||||
type: 'action' as const
|
||||
})),
|
||||
// Reset debug mode item
|
||||
{
|
||||
displayName: 'Reset debug mode',
|
||||
action: () => {
|
||||
$componentControl?.[id]?.setTab?.(0)
|
||||
$debuggingComponents = Object.fromEntries(
|
||||
Object.entries($debuggingComponents).filter(([key]) => key !== id)
|
||||
)
|
||||
},
|
||||
type: 'delete' as const
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
{#key renderCount}
|
||||
<button
|
||||
title={'Debug tabs'}
|
||||
class={classNames(
|
||||
'px-1 text-2xs font-bold rounded cursor-pointer w-fit h-full',
|
||||
componentIsDebugging
|
||||
? ' hover:bg-red-300 hover:text-red-800'
|
||||
: 'text-blue-600 hover:bg-blue-300 hover:text-blue-800'
|
||||
)}
|
||||
on:click={() => dispatch('triggerInlineEditor')}
|
||||
on:pointerdown|stopPropagation
|
||||
>
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<div class="px-1 w-fit">
|
||||
{#if componentIsDebugging}
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
{`${isSmall ? '' : 'Debugging node'} ${nodes[$debuggingComponents[id] ?? 0]?.id}`}
|
||||
<button
|
||||
on:click={() => {
|
||||
$componentControl?.[id]?.setTab?.(0)
|
||||
<Dropdown items={getDropdownItems} class="w-fit h-auto" usePointerDownOutside={true}>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<button
|
||||
title={'Debug tabs'}
|
||||
class={classNames(
|
||||
'px-1 text-2xs font-bold rounded cursor-pointer w-fit h-full',
|
||||
componentIsDebugging
|
||||
? ' hover:bg-red-300 hover:text-red-800'
|
||||
: 'text-blue-600 hover:bg-blue-300 hover:text-blue-800'
|
||||
)}
|
||||
on:click={() => dispatch('triggerInlineEditor')}
|
||||
on:pointerdown|stopPropagation
|
||||
>
|
||||
{#if componentIsDebugging}
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
{`${isSmall ? '' : 'Debugging node'} ${nodes[$debuggingComponents[id] ?? 0]?.id}`}
|
||||
<button
|
||||
on:click={() => {
|
||||
$componentControl?.[id]?.setTab?.(0)
|
||||
|
||||
$debuggingComponents = Object.fromEntries(
|
||||
Object.entries($debuggingComponents).filter(([key]) => key !== id)
|
||||
)
|
||||
}}
|
||||
>
|
||||
<X size={11} />
|
||||
</button>
|
||||
</div>
|
||||
{:else if isSmall}
|
||||
<div class="flex h-full w-fit items-center"><Bug size={11} /></div>
|
||||
{:else}<div class="whitespace-nowrap h-full"
|
||||
>{`Debug nodes (current node: ${currentNodeId})`}</div
|
||||
>{/if}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
{#each nodes ?? [] as node, index}
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
$componentControl?.[id]?.setTab?.(index)
|
||||
|
||||
$debuggingComponents[id] = index
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-tertiary text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
$debuggingComponents = Object.fromEntries(
|
||||
Object.entries($debuggingComponents).filter(([key]) => key !== id)
|
||||
)
|
||||
}}
|
||||
>
|
||||
{`Debug node ${node.label}`}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/each}
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
$componentControl?.[id]?.setTab?.(0)
|
||||
|
||||
$debuggingComponents = Object.fromEntries(
|
||||
Object.entries($debuggingComponents).filter(([key]) => key !== id)
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-red-600 text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{`Reset debug mode`}
|
||||
<X size={11} />
|
||||
</button>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
{:else if isSmall}
|
||||
<div class="flex h-full w-fit items-center"><Bug size={11} /></div>
|
||||
{:else}<div class="whitespace-nowrap h-full"
|
||||
>{`Debug nodes (current node: ${currentNodeId})`}</div
|
||||
>{/if}
|
||||
</button>
|
||||
</svelte:fragment>
|
||||
</Dropdown>
|
||||
{/key}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Loader2, RefreshCw, TimerReset } from 'lucide-svelte'
|
||||
import Button from '../../common/button/Button.svelte'
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { classNames } from '$lib/utils'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import Badge from '$lib/components/common/badge/Badge.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@@ -54,53 +52,20 @@
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<slot:fragment slot="buttonReplacement">
|
||||
<Dropdown {items} class="w-fit h-auto">
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<div class="flex flex-row gap-2 text-xs hover:bg-surface-hover px-2 items-center h-7">
|
||||
{#if interval}
|
||||
<Badge color="blue" small>
|
||||
{interval ? `Every ${interval / 1000}s` : 'Once'}
|
||||
</Badge>
|
||||
{/if}
|
||||
|
||||
<div class="flex justify-center items-center">
|
||||
<TimerReset size={14} />
|
||||
</div>
|
||||
</div>
|
||||
</slot:fragment>
|
||||
<svelte:fragment slot="label">
|
||||
<span
|
||||
class={twMerge('text-xs min-w-[2rem] ', interval ? 'text-blue-500' : 'text-tertiary')}
|
||||
>
|
||||
{interval ? `${interval / 1000}s` : 'Once'}
|
||||
</span>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
{#each items ?? [] as { }, index}
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
if (index === 0) {
|
||||
dispatch('setInter', undefined)
|
||||
} else {
|
||||
dispatch('setInter', index * 5000)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-tertiary text-left px-4 py-2 gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{#if index === 0}
|
||||
Once
|
||||
{:else}
|
||||
{`Every ${index * 5} seconds`}
|
||||
{/if}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/each}
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</Dropdown>
|
||||
</div>
|
||||
{#if interval}
|
||||
<div class="w-full bg-gray-200 rounded-full h-0.5 dark:bg-gray-700">
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { AppViewerContext } from '../types'
|
||||
import { Bug } from 'lucide-svelte'
|
||||
@@ -17,22 +16,50 @@
|
||||
|
||||
export let isManuallySelected: boolean = false
|
||||
let selected: number | null = null
|
||||
|
||||
async function getItems() {
|
||||
return [
|
||||
...tabs.map((_, index) => ({
|
||||
displayName:
|
||||
index === tabs.length - 1
|
||||
? isConditionalDebugMode
|
||||
? `Debug default condition`
|
||||
: `Debug tab ${index + 1}`
|
||||
: `Debug ${isConditionalDebugMode ? 'condition' : 'tab'} ${index + 1}`,
|
||||
action: () => {
|
||||
$componentControl?.[id]?.setTab?.(index)
|
||||
selected = index
|
||||
isManuallySelected = true
|
||||
},
|
||||
type: 'action' as const
|
||||
})),
|
||||
{
|
||||
displayName: 'Reset debug mode',
|
||||
action: () => {
|
||||
$componentControl?.[id]?.setTab?.(-1)
|
||||
selected = null
|
||||
isManuallySelected = false
|
||||
},
|
||||
type: 'delete' as const
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<button
|
||||
title={isConditionalDebugMode ? 'Debug conditions' : 'Debug tabs'}
|
||||
class={classNames(
|
||||
'text-2xs font-bold w-fit h-full cursor-pointer rounded',
|
||||
isManuallySelected
|
||||
? 'hover:bg-red-200 hover:text-red-800'
|
||||
: 'text-blue-600 hover:bg-blue-300 hover:text-blue-800'
|
||||
)}
|
||||
on:click={() => dispatch('triggerInlineEditor')}
|
||||
on:pointerdown|stopPropagation
|
||||
>
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
{#key tabs}
|
||||
<Dropdown items={getItems} class="w-fit h-auto" usePointerDownOutside>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<div class="px-1">
|
||||
<button
|
||||
title={isConditionalDebugMode ? 'Debug conditions' : 'Debug tabs'}
|
||||
class={classNames(
|
||||
'px-1 text-2xs font-bold w-fit h-full cursor-pointer rounded',
|
||||
isManuallySelected
|
||||
? 'hover:bg-red-200 hover:text-red-800'
|
||||
: 'text-blue-600 hover:bg-blue-300 hover:text-blue-800'
|
||||
)}
|
||||
on:click={() => dispatch('triggerInlineEditor')}
|
||||
on:pointerdown|stopPropagation
|
||||
>
|
||||
{#if isManuallySelected}
|
||||
<div class="whitespace-nowrap">
|
||||
{#if selected === tabs.length - 1}
|
||||
@@ -51,45 +78,7 @@
|
||||
{:else if isSmall}<Bug size={11} />{:else}
|
||||
{isConditionalDebugMode ? `Debug conditions` : `Debug tabs`}
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
{#each tabs ?? [] as { }, index}
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
$componentControl?.[id]?.setTab?.(index)
|
||||
selected = index
|
||||
isManuallySelected = true
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-tertiary text-left px-4 py-2 gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{#if index === tabs.length - 1}
|
||||
{isConditionalDebugMode ? `Debug default condition` : `Debug tab ${index + 1}`}
|
||||
{:else}
|
||||
{`Debug ${isConditionalDebugMode ? 'condition' : 'tab'} ${index + 1}`}
|
||||
{/if}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/each}
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
$componentControl?.[id]?.setTab?.(-1)
|
||||
selected = null
|
||||
isManuallySelected = false
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-red-600 dark:!text-red-400 text-left px-4 py-2 gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{`Reset debug mode`}
|
||||
</div>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
</Dropdown>
|
||||
{/key}
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
|
||||
import { Trash } from 'lucide-svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import NameEditor from './NameEditor.svelte'
|
||||
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { ResourceService } from '$lib/gen'
|
||||
|
||||
export let row: {
|
||||
@@ -52,6 +48,17 @@
|
||||
|
||||
sendUserToast('Component name updated:\n' + name)
|
||||
}
|
||||
|
||||
function getItems() {
|
||||
return [
|
||||
{
|
||||
action: toggleDelete,
|
||||
icon: Trash,
|
||||
displayName: 'Delete',
|
||||
type: 'delete' as const
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<tr>
|
||||
@@ -69,23 +76,6 @@
|
||||
</Cell>
|
||||
|
||||
<Cell last>
|
||||
<div class={twMerge('flex flex-row gap-1 justify-end z-[10000]')}>
|
||||
<button on:pointerdown|stopPropagation>
|
||||
<ButtonDropdown target="#cc_portal" hasPadding={false}>
|
||||
<svelte:fragment slot="items">
|
||||
<MenuItem on:click={toggleDelete}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-red-600 flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
<Trash size={16} />
|
||||
Delete
|
||||
</div>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
</div>
|
||||
<Dropdown items={getItems()} />
|
||||
</Cell>
|
||||
</tr>
|
||||
|
||||
@@ -69,8 +69,6 @@
|
||||
getCustomComponents()
|
||||
</script>
|
||||
|
||||
<div id="cc_portal" />
|
||||
|
||||
<div class="p-2 flex flex-col items-start w-auto gap-2 relative">
|
||||
<div class="w-full flex flex-col gap-y-2 pb-8">
|
||||
<div>
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
import { deleteGroup, getGroup, updateGroup } from './groupUtils'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import Cell from '$lib/components/table/Cell.svelte'
|
||||
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { Trash } from 'lucide-svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import GroupNameEditor from './NameEditor.svelte'
|
||||
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
|
||||
export let row: {
|
||||
name: string
|
||||
path: string
|
||||
@@ -27,6 +22,17 @@
|
||||
dispatch('reloadGroups')
|
||||
sendUserToast('Group deleted:\n' + row.name)
|
||||
}
|
||||
|
||||
function getItems() {
|
||||
return [
|
||||
{
|
||||
action: toggleDelete,
|
||||
icon: Trash,
|
||||
displayName: 'Delete',
|
||||
type: 'delete' as const
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<tr>
|
||||
@@ -54,23 +60,6 @@
|
||||
</Cell>
|
||||
|
||||
<Cell last>
|
||||
<div class={twMerge('flex flex-row gap-1 justify-end z-[10000]')}>
|
||||
<button on:pointerdown|stopPropagation>
|
||||
<ButtonDropdown target="#group_portal" hasPadding={false}>
|
||||
<svelte:fragment slot="items">
|
||||
<MenuItem on:click={toggleDelete}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-red-600 flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
<Trash size={16} />
|
||||
Delete
|
||||
</div>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
</div>
|
||||
<Dropdown items={getItems()} />
|
||||
</Cell>
|
||||
</tr>
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
import ThemeNameEditor from './ThemeNameEditor.svelte'
|
||||
|
||||
import ThemeDrawer from './ThemeDrawer.svelte'
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
|
||||
export let previewThemePath: string | undefined = undefined
|
||||
|
||||
@@ -134,6 +132,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function getDropdownItems() {
|
||||
return [
|
||||
{
|
||||
action: () => themeDrawer?.openDrawer(),
|
||||
icon: Code,
|
||||
displayName: 'View code',
|
||||
type: 'action' as const
|
||||
},
|
||||
{
|
||||
action: () => fork(row.path),
|
||||
icon: GitBranch,
|
||||
displayName: 'Fork',
|
||||
type: 'action' as const
|
||||
},
|
||||
{
|
||||
action: () => makeDefaultTheme(row.path),
|
||||
icon: Pin,
|
||||
displayName: 'Make default',
|
||||
type: 'action' as const,
|
||||
disabled: row.path === DEFAULT_THEME
|
||||
},
|
||||
{
|
||||
action: toggleDelete,
|
||||
icon: Trash,
|
||||
displayName: 'Delete',
|
||||
type: 'delete' as const,
|
||||
disabled: row.path === DEFAULT_THEME
|
||||
}
|
||||
]
|
||||
}
|
||||
let themeDrawer: ThemeDrawer
|
||||
</script>
|
||||
|
||||
@@ -172,55 +200,7 @@
|
||||
<Button color="dark" size="xs2" on:click={apply}>Apply</Button>
|
||||
{/if}
|
||||
|
||||
<button on:pointerdown|stopPropagation>
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<svelte:fragment slot="items">
|
||||
<MenuItem on:click={() => themeDrawer?.openDrawer()}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-primary flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
<Code size={16} />
|
||||
View code
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem on:click={() => fork(row.path)}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-primary flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
<GitBranch size={16} />
|
||||
Fork
|
||||
</div>
|
||||
</MenuItem>
|
||||
{#if row.path !== DEFAULT_THEME}
|
||||
<MenuItem on:click={() => makeDefaultTheme(row.path)}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-primary flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
<Pin size={16} />
|
||||
Make default
|
||||
</div>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem on:click={toggleDelete}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-red-600 flex flex-row items-center text-left px-4 py-2 gap-2 cursor-pointer hover:bg-gray-100 !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
<Trash size={16} />
|
||||
Delete
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</button>
|
||||
<Dropdown items={getDropdownItems} />
|
||||
</div>
|
||||
</Cell>
|
||||
</tr>
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { ButtonType } from './model'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import ButtonDropdown from './ButtonDropdown.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { classNames, getModifierKey } from '$lib/utils'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import { getModifierKey, type Item } from '$lib/utils'
|
||||
import { Loader2, ChevronDown } from 'lucide-svelte'
|
||||
|
||||
export let size: ButtonType.Size = 'md'
|
||||
export let spacingSize: ButtonType.Size = size
|
||||
@@ -30,7 +29,6 @@
|
||||
export let title: string | undefined = undefined
|
||||
export let style: string = ''
|
||||
export let download: string | undefined = undefined
|
||||
export let portalTarget: string | undefined = undefined
|
||||
export let startIcon: ButtonType.Icon | undefined = undefined
|
||||
export let endIcon: ButtonType.Icon | undefined = undefined
|
||||
export let shortCut:
|
||||
@@ -45,12 +43,14 @@
|
||||
}
|
||||
export let dropdownItems: MenuItem[] | (() => MenuItem[]) | undefined = undefined
|
||||
|
||||
function computeDropdowns(): MenuItem[] | undefined {
|
||||
if (typeof dropdownItems === 'function') {
|
||||
return dropdownItems()
|
||||
} else {
|
||||
return dropdownItems
|
||||
}
|
||||
function computeDropdowns(menuItems: MenuItem[] | (() => MenuItem[])): Item[] {
|
||||
const items = typeof menuItems === 'function' ? menuItems() : menuItems
|
||||
return items.map((item) => ({
|
||||
displayName: item.label,
|
||||
action: item.onClick ? (e) => item.onClick?.(e) : undefined,
|
||||
icon: item.icon,
|
||||
href: item.href
|
||||
}))
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
@@ -230,32 +230,19 @@
|
||||
{/if}
|
||||
|
||||
{#if dropdownItems && dropdownItems.length > 0}
|
||||
<div
|
||||
class={twMerge(
|
||||
buttonClass,
|
||||
'rounded-md m-0 p-0 h-auto !w-10',
|
||||
variant === 'border' ? 'border-0 border-r border-y ' : 'border-0',
|
||||
'rounded-r-md !rounded-l-none'
|
||||
)}
|
||||
>
|
||||
<ButtonDropdown target={portalTarget}>
|
||||
<svelte:fragment slot="items">
|
||||
{#each computeDropdowns() ?? [] as item}
|
||||
<MenuItem on:click={item.onClick} href={item.href}>
|
||||
<div
|
||||
class={classNames(
|
||||
'!text-secondary text-left px-4 py-2 gap-2 cursor-pointer hover:bg-surface-hover !text-xs font-semibold'
|
||||
)}
|
||||
>
|
||||
{#if item.icon}
|
||||
<svelte:component this={item.icon} class="w-4 h-4" size={lucideIconSize} />
|
||||
{/if}
|
||||
{item.label}
|
||||
</div>
|
||||
</MenuItem>
|
||||
{/each}
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</div>
|
||||
<Dropdown items={computeDropdowns(dropdownItems)} class="h-full">
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<div
|
||||
class={twMerge(
|
||||
buttonClass,
|
||||
'rounded-md m-0 p-0 !w-10 center-center h-full',
|
||||
variant === 'border' ? 'border-0 border-r border-y ' : 'border-0',
|
||||
'rounded-r-md !rounded-l-none'
|
||||
)}
|
||||
>
|
||||
<ChevronDown class="w-5 h-5" />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</Dropdown>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import Portal from '$lib/components/Portal.svelte'
|
||||
import { melt, createSync } from '@melt-ui/svelte'
|
||||
import type { Placement } from '@floating-ui/core'
|
||||
import { pointerDownOutside } from '$lib/utils'
|
||||
@@ -65,20 +64,16 @@
|
||||
<slot name="trigger" trigger={$trigger} />
|
||||
</button>
|
||||
|
||||
<Portal name="menu-v3">
|
||||
<div class="z-[6000]" use:melt={$menuElement} data-menu>
|
||||
<div
|
||||
class={twMerge(
|
||||
'border w-56 origin-top-right rounded-md shadow-md focus:outline-none overflow-y-auto',
|
||||
lightMode ? 'bg-surface-inverse' : 'bg-surface',
|
||||
invisible ? 'opacity-0' : ''
|
||||
)}
|
||||
style="max-height: {maxHeight}px;"
|
||||
>
|
||||
<div class="my-1">
|
||||
<slot item={$item} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Portal>
|
||||
<div
|
||||
class={twMerge(
|
||||
'z-[6000] border w-56 origin-top-right rounded-md shadow-md focus:outline-none overflow-y-auto py-1',
|
||||
lightMode ? 'bg-surface-inverse' : 'bg-surface',
|
||||
invisible ? 'opacity-0' : ''
|
||||
)}
|
||||
style="max-height: {maxHeight}px;"
|
||||
use:melt={$menuElement}
|
||||
data-menu
|
||||
>
|
||||
<slot item={$item} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<Tutorial
|
||||
bind:this={tutorial}
|
||||
index={0}
|
||||
index={4}
|
||||
name="error-handler"
|
||||
tainted={false}
|
||||
on:error
|
||||
|
||||
@@ -1112,3 +1112,14 @@ export function conditionalMelt(node: HTMLElement, meltElement: any) {
|
||||
}
|
||||
return { destroy: () => {} }
|
||||
}
|
||||
|
||||
export type Item = {
|
||||
displayName: string
|
||||
action?: (e: CustomEvent<any>) => void
|
||||
icon?: any
|
||||
iconColor?: string
|
||||
href?: string
|
||||
disabled?: boolean
|
||||
type?: 'action' | 'delete'
|
||||
hide?: boolean | undefined
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
Skeleton,
|
||||
Tab,
|
||||
Alert,
|
||||
MenuItem,
|
||||
DrawerContent
|
||||
} from '$lib/components/common'
|
||||
import FlowMetadata from '$lib/components/FlowMetadata.svelte'
|
||||
@@ -79,7 +78,7 @@
|
||||
import { goto } from '$lib/navigation'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { forLater } from '$lib/forLater'
|
||||
import ButtonDropdown from '$lib/components/common/button/ButtonDropdown.svelte'
|
||||
import Dropdown from '$lib/components/DropdownV2.svelte'
|
||||
import PersistentScriptDrawer from '$lib/components/PersistentScriptDrawer.svelte'
|
||||
import Portal from '$lib/components/Portal.svelte'
|
||||
|
||||
@@ -442,20 +441,21 @@
|
||||
{@const runsHref = `/runs/${job?.script_path}${!isScript ? '?jobKind=flow' : ''}`}
|
||||
<div class="flex gap-2 items-center">
|
||||
{#if job && 'deleted' in job && !job?.deleted && ($superadmin || ($userStore?.is_admin ?? false))}
|
||||
<ButtonDropdown target="body" hasPadding={false}>
|
||||
<Dropdown
|
||||
items={[
|
||||
{
|
||||
displayName: 'Delete result, logs and args (admin only)',
|
||||
action: () => {
|
||||
job?.id && deleteCompletedJob(job.id)
|
||||
},
|
||||
type: 'delete'
|
||||
}
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button nonCaptureEvent variant="border" size="sm" startIcon={{ icon: Trash }} />
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
<MenuItem
|
||||
on:click={() => {
|
||||
job?.id && deleteCompletedJob(job.id)
|
||||
}}
|
||||
>
|
||||
<span class="text-red-600"> Delete result, logs and args (admin only) </span>
|
||||
</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</Dropdown>
|
||||
{#if job?.job_kind === 'script' || job?.job_kind === 'flow'}
|
||||
<Button
|
||||
href={runsHref}
|
||||
@@ -474,9 +474,19 @@
|
||||
{@const stem = `/${job?.job_kind}s`}
|
||||
{@const isScript = job?.job_kind === 'script'}
|
||||
{@const viewHref = `${stem}/get/${isScript ? job?.script_hash : job?.script_path}`}
|
||||
{#if (job?.job_kind == 'flow' || isFlowPreview(job?.job_kind)) && job?.['running'] && job?.parent_job == undefined}
|
||||
{#if ((job?.job_kind == 'flow' || isFlowPreview(job?.job_kind)) && job?.['running'] && job?.parent_job == undefined) || true}
|
||||
<div class="inline">
|
||||
<ButtonDropdown hasPadding={false}>
|
||||
<Dropdown
|
||||
items={[
|
||||
{
|
||||
displayName: 'Show Flow Debug Info',
|
||||
action: () => {
|
||||
debugInfo()
|
||||
}
|
||||
}
|
||||
]}
|
||||
class="h-auto"
|
||||
>
|
||||
<svelte:fragment slot="buttonReplacement">
|
||||
<Button nonCaptureEvent size="xs" color="light">
|
||||
<div class="flex flex-row items-center">
|
||||
@@ -484,10 +494,7 @@
|
||||
</div>
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="items">
|
||||
<MenuItem on:click={debugInfo}>Show Flow Debug Info</MenuItem>
|
||||
</svelte:fragment>
|
||||
</ButtonDropdown>
|
||||
</Dropdown>
|
||||
</div>
|
||||
{/if}
|
||||
{#if isFlowPreview(job?.job_kind) || isScriptPreview(job?.job_kind)}
|
||||
|
||||
Reference in New Issue
Block a user