mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-23 16:00:38 +00:00
nits
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onDestroy } from 'svelte'
|
||||
import { getContext, onDestroy, untrack } from 'svelte'
|
||||
|
||||
import type {
|
||||
AppViewerContext,
|
||||
@@ -18,18 +18,28 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import ResolveStyle from '../helpers/ResolveStyle.svelte'
|
||||
|
||||
export let id: string
|
||||
export let configuration: RichConfigurations
|
||||
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = undefined
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
export let customCss: ComponentCustomCSS<'selecttabcomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
interface Props {
|
||||
id: string
|
||||
configuration: RichConfigurations
|
||||
horizontalAlignment?: 'left' | 'center' | 'right' | undefined
|
||||
verticalAlignment?: 'top' | 'center' | 'bottom' | undefined
|
||||
customCss?: ComponentCustomCSS<'selecttabcomponent'> | undefined
|
||||
render: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
id,
|
||||
configuration,
|
||||
horizontalAlignment = undefined,
|
||||
verticalAlignment = undefined,
|
||||
customCss = undefined,
|
||||
render
|
||||
}: Props = $props()
|
||||
|
||||
const { app, worldStore, componentControl } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const resolvedConfig = initConfig(
|
||||
components['selecttabcomponent'].initialData.configuration,
|
||||
configuration
|
||||
const resolvedConfig = $state(
|
||||
initConfig(components['selecttabcomponent'].initialData.configuration, configuration)
|
||||
)
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: undefined as string | undefined
|
||||
@@ -38,8 +48,7 @@
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
let selected: string = ''
|
||||
$: selected === '' && resolvedConfig && setDefaultValue()
|
||||
let selected: string = $state('')
|
||||
|
||||
onDestroy(() => {
|
||||
listInputs?.remove(id)
|
||||
@@ -51,6 +60,11 @@
|
||||
},
|
||||
setTab(index) {
|
||||
selected = resolvedConfig.items?.[index]?.value
|
||||
},
|
||||
setSelectedIndex(index) {
|
||||
if (index >= 0 && index < resolvedConfig.items?.length) {
|
||||
selected = resolvedConfig.items?.[index]?.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +83,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: selected && handleSelection(selected)
|
||||
let css = initCss($app.css?.selecttabcomponent, customCss)
|
||||
let css = $state(initCss($app.css?.selecttabcomponent, customCss))
|
||||
$effect.pre(() => {
|
||||
selected === '' && resolvedConfig.defaultValue && untrack(() => setDefaultValue())
|
||||
})
|
||||
$effect.pre(() => {
|
||||
selected && untrack(() => handleSelection(selected))
|
||||
})
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['selecttabcomponent'].initialData.configuration) as key (key)}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { getContext, untrack } from 'svelte'
|
||||
import { initOutput } from '../../editor/appUtils'
|
||||
import SubGridEditor from '../../editor/SubGridEditor.svelte'
|
||||
import type { AppViewerContext, ComponentCustomCSS } from '../../types'
|
||||
@@ -14,16 +14,31 @@
|
||||
import RunnableComponent from '../helpers/RunnableComponent.svelte'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
|
||||
export let id: string
|
||||
export let componentContainerHeight: number
|
||||
export let tabs: string[]
|
||||
export let customCss: ComponentCustomCSS<'steppercomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
export let recomputeIds: string[] | undefined = undefined
|
||||
export let extraQueryParams: Record<string, any> = {}
|
||||
export let componentInput: AppInput | undefined
|
||||
export let onNext: string[] | undefined = undefined
|
||||
export let onPrevious: string[] | undefined = undefined
|
||||
interface Props {
|
||||
id: string
|
||||
componentContainerHeight: number
|
||||
tabs: string[]
|
||||
customCss?: ComponentCustomCSS<'steppercomponent'> | undefined
|
||||
render: boolean
|
||||
recomputeIds?: string[] | undefined
|
||||
extraQueryParams?: Record<string, any>
|
||||
componentInput: AppInput | undefined
|
||||
onNext?: string[] | undefined
|
||||
onPrevious?: string[] | undefined
|
||||
}
|
||||
|
||||
let {
|
||||
id,
|
||||
componentContainerHeight,
|
||||
tabs,
|
||||
customCss = undefined,
|
||||
render,
|
||||
recomputeIds = undefined,
|
||||
extraQueryParams = {},
|
||||
componentInput,
|
||||
onNext = undefined,
|
||||
onPrevious = undefined
|
||||
}: Props = $props()
|
||||
|
||||
const {
|
||||
app,
|
||||
@@ -36,16 +51,18 @@
|
||||
runnableComponents
|
||||
} = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let everRender = render
|
||||
$: render && !everRender && (everRender = true)
|
||||
let everRender = $state(render)
|
||||
$effect.pre(() => {
|
||||
render && !everRender && (everRender = true)
|
||||
})
|
||||
|
||||
let selected = tabs[0]
|
||||
let tabHeight: number = 0
|
||||
let footerHeight: number = 0
|
||||
let runnableComponent: RunnableComponent
|
||||
let selectedIndex = tabs?.indexOf(selected) ?? -1
|
||||
let maxReachedIndex = -1
|
||||
let statusByStep = [] as Array<'success' | 'error' | 'pending'>
|
||||
let selected = $state(tabs[0])
|
||||
let tabHeight: number = $state(0)
|
||||
let footerHeight: number = $state(0)
|
||||
let runnableComponent: RunnableComponent | undefined = $state()
|
||||
let selectedIndex = $state(tabs?.indexOf(selected) ?? -1)
|
||||
let maxReachedIndex = $state(-1)
|
||||
let statusByStep = $state([] as Array<'success' | 'error' | 'pending'>)
|
||||
let debugMode: boolean = false
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
@@ -74,7 +91,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
let result: { error: { name: string; message: string; stack: string } } | undefined = undefined
|
||||
let result: { error: { name: string; message: string; stack: string } } | undefined =
|
||||
$state(undefined)
|
||||
|
||||
async function runStep(targetIndex: number) {
|
||||
statusByStep[selectedIndex] = 'pending'
|
||||
@@ -122,14 +140,22 @@
|
||||
}
|
||||
|
||||
handleTabSelection()
|
||||
},
|
||||
setSelectedIndex(index) {
|
||||
if (index >= 0 && index < tabs.length) {
|
||||
selected = tabs[index]
|
||||
handleTabSelection()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$: selected != undefined && handleTabSelection()
|
||||
let css = initCss($app.css?.steppercomponent, customCss)
|
||||
$: lastStep = selectedIndex === tabs.length - 1
|
||||
$effect.pre(() => {
|
||||
selected != undefined && untrack(() => handleTabSelection())
|
||||
})
|
||||
let css = $state(initCss($app.css?.steppercomponent, customCss))
|
||||
let lastStep = $derived(selectedIndex === tabs.length - 1)
|
||||
|
||||
let directionClicked: 'left' | 'right' | undefined = undefined
|
||||
let directionClicked: 'left' | 'right' | undefined = $state(undefined)
|
||||
</script>
|
||||
|
||||
{#each Object.keys(css ?? {}) as key (key)}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { createBubbler, stopPropagation } from 'svelte/legacy'
|
||||
|
||||
const bubble = createBubbler()
|
||||
import { Tab, Tabs } from '$lib/components/common'
|
||||
import { getContext } from 'svelte'
|
||||
import { getContext, untrack } from 'svelte'
|
||||
import { initConfig, initOutput } from '../../editor/appUtils'
|
||||
import { components } from '../../editor/component'
|
||||
import SubGridEditor from '../../editor/SubGridEditor.svelte'
|
||||
@@ -16,21 +19,35 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import ResolveStyle from '../helpers/ResolveStyle.svelte'
|
||||
|
||||
export let id: string
|
||||
export let configuration: RichConfigurations
|
||||
export let componentContainerHeight: number
|
||||
export let tabs: string[]
|
||||
export let customCss: ComponentCustomCSS<'tabscomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
export let disabledTabs: RichConfiguration[]
|
||||
export let onTabChange: string[] | undefined = undefined
|
||||
interface Props {
|
||||
id: string
|
||||
configuration: RichConfigurations
|
||||
componentContainerHeight: number
|
||||
tabs: string[]
|
||||
customCss?: ComponentCustomCSS<'tabscomponent'> | undefined
|
||||
render: boolean
|
||||
disabledTabs: RichConfiguration[]
|
||||
onTabChange?: string[] | undefined
|
||||
}
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['tabscomponent'].initialData.configuration,
|
||||
configuration
|
||||
let {
|
||||
id,
|
||||
configuration,
|
||||
componentContainerHeight,
|
||||
tabs,
|
||||
customCss = undefined,
|
||||
render,
|
||||
disabledTabs,
|
||||
onTabChange = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let resolvedConfig = $state(
|
||||
initConfig(components['tabscomponent'].initialData.configuration, configuration)
|
||||
)
|
||||
let everRender = render
|
||||
$: render && !everRender && (everRender = true)
|
||||
let everRender = $state(render)
|
||||
$effect.pre(() => {
|
||||
render && !everRender && (everRender = true)
|
||||
})
|
||||
|
||||
const {
|
||||
app,
|
||||
@@ -43,8 +60,11 @@
|
||||
runnableComponents
|
||||
} = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let selected: string = tabs[0]
|
||||
let tabHeight: number = 0
|
||||
let selected: string = $state(tabs[0])
|
||||
let selectedIndex = $state(tabs?.indexOf(selected) ?? -1)
|
||||
let css = $state(initCss($app.css?.tabscomponent, customCss))
|
||||
|
||||
let tabHeight: number = $state(0)
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
selectedTabIndex: 0
|
||||
@@ -53,7 +73,14 @@
|
||||
const titleBarHeight = 40 // Example height of a single accordion title bar in pixels
|
||||
|
||||
function handleTabSelection() {
|
||||
let oldSelectedIndex = selectedIndex
|
||||
selectedIndex = tabs?.indexOf(selected)
|
||||
if (selectedIndex == -1) {
|
||||
selectedIndex = oldSelectedIndex
|
||||
if (selectedIndex != -1 && tabs.length > 0) {
|
||||
selected = tabs[selectedIndex]
|
||||
}
|
||||
}
|
||||
outputs?.selectedTabIndex.set(selectedIndex)
|
||||
|
||||
onTabChange?.forEach((id) => $runnableComponents?.[id]?.cb?.forEach((cb) => cb?.()))
|
||||
@@ -67,6 +94,11 @@
|
||||
}
|
||||
|
||||
$componentControl[id] = {
|
||||
setSelectedIndex(index) {
|
||||
if (index >= 0 && index < tabs.length) {
|
||||
selected = tabs[index]
|
||||
}
|
||||
},
|
||||
left: () => {
|
||||
const index = tabs.indexOf(selected)
|
||||
if (index > 0) {
|
||||
@@ -89,11 +121,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: selected != undefined && handleTabSelection()
|
||||
let selectedIndex = tabs?.indexOf(selected) ?? -1
|
||||
let css = initCss($app.css?.tabscomponent, customCss)
|
||||
$effect.pre(() => {
|
||||
tabs
|
||||
selected != undefined && untrack(() => handleTabSelection())
|
||||
})
|
||||
|
||||
let resolvedDisabledTabs: boolean[] = []
|
||||
let resolvedDisabledTabs: boolean[] = $state([])
|
||||
</script>
|
||||
|
||||
<InputValue key="kind" {id} input={configuration.tabsKind} bind:value={resolvedConfig.tabsKind} />
|
||||
@@ -153,8 +186,8 @@
|
||||
>
|
||||
{#each tabs ?? [] as res, index}
|
||||
<button
|
||||
on:pointerdown|stopPropagation
|
||||
on:click={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
onpointerdown={stopPropagation(bubble('pointerdown'))}
|
||||
onclick={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
disabled={resolvedDisabledTabs[index]}
|
||||
class={twMerge(
|
||||
'rounded-sm !truncate text-sm hover:text-primary px-1 py-2',
|
||||
@@ -167,7 +200,9 @@
|
||||
'wm-tabs-selectedTab'
|
||||
)
|
||||
: '',
|
||||
resolvedDisabledTabs[index] ? 'opacity-50 cursor-not-allowed hover:text-secondary' : ''
|
||||
resolvedDisabledTabs[index]
|
||||
? 'opacity-50 cursor-not-allowed hover:text-secondary'
|
||||
: ''
|
||||
)}
|
||||
style={selected == res
|
||||
? [css?.allTabs?.style, css?.selectedTab?.style].filter(Boolean).join(';')
|
||||
@@ -183,8 +218,8 @@
|
||||
{#each tabs ?? [] as res, index}
|
||||
<div class="border-b">
|
||||
<button
|
||||
on:pointerdown|stopPropagation
|
||||
on:click={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
onpointerdown={stopPropagation(bubble('pointerdown'))}
|
||||
onclick={() => !resolvedDisabledTabs[index] && (selected = res)}
|
||||
disabled={resolvedDisabledTabs[index]}
|
||||
class={twMerge(
|
||||
'w-full text-left bg-surface !truncate text-sm hover:text-primary px-1 py-2',
|
||||
@@ -197,7 +232,9 @@
|
||||
'wm-tabs-selectedTab'
|
||||
)
|
||||
: 'text-secondary',
|
||||
resolvedDisabledTabs[index] ? 'opacity-50 cursor-not-allowed hover:text-secondary' : ''
|
||||
resolvedDisabledTabs[index]
|
||||
? 'opacity-50 cursor-not-allowed hover:text-secondary'
|
||||
: ''
|
||||
)}
|
||||
>
|
||||
<span class="mr-2 w-8 font-mono">{selected == res ? '-' : '+'}</span>
|
||||
|
||||
@@ -85,11 +85,11 @@ const validateAll = {
|
||||
export function getComponentControl(type: keyof typeof components): Array<ComponentFunction> {
|
||||
switch (type) {
|
||||
case 'tabscomponent':
|
||||
return [setTab]
|
||||
return [setTab, setSelectedIndex]
|
||||
case 'selectstepcomponent':
|
||||
return [setTab, setValue]
|
||||
return [setTab, setValue, setSelectedIndex]
|
||||
case 'selecttabcomponent':
|
||||
return [setTab, setValue]
|
||||
return [setTab, setValue, setSelectedIndex]
|
||||
case 'conditionalwrapper':
|
||||
case 'steppercomponent':
|
||||
return [setTab]
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { createBubbler, stopPropagation } from 'svelte/legacy'
|
||||
|
||||
const bubble = createBubbler()
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import CloseButton from '$lib/components/common/CloseButton.svelte'
|
||||
import { getContext, tick } from 'svelte'
|
||||
import { getContext, tick, untrack } from 'svelte'
|
||||
import type { AppViewerContext, RichConfiguration } from '../../types'
|
||||
import { deleteGridItem } from '../appUtils'
|
||||
import type { AppComponent } from '../component'
|
||||
@@ -11,27 +14,43 @@
|
||||
import { GripVertical, Plus } from 'lucide-svelte'
|
||||
import GridTabDisabled from './GridTabDisabled.svelte'
|
||||
|
||||
export let tabs: string[] = []
|
||||
export let disabledTabs: RichConfiguration[] = []
|
||||
|
||||
export let canDisableTabs: boolean = false
|
||||
|
||||
export let word: string = 'Tab'
|
||||
|
||||
export let component: AppComponent
|
||||
|
||||
$: if (disabledTabs == undefined) {
|
||||
disabledTabs = [
|
||||
{ type: 'static', value: false, fieldType: 'boolean' },
|
||||
{ type: 'static', value: false, fieldType: 'boolean' }
|
||||
]
|
||||
interface Props {
|
||||
tabs?: string[]
|
||||
disabledTabs?: RichConfiguration[]
|
||||
canDisableTabs?: boolean
|
||||
word?: string
|
||||
component: AppComponent
|
||||
}
|
||||
|
||||
let items = tabs.map((tab, index) => {
|
||||
return { value: tab, id: generateRandomString(), originalIndex: index }
|
||||
let {
|
||||
tabs = $bindable([]),
|
||||
disabledTabs = $bindable([]),
|
||||
canDisableTabs = false,
|
||||
word = 'Tab',
|
||||
component = $bindable()
|
||||
}: Props = $props()
|
||||
|
||||
$effect.pre(() => {
|
||||
if (disabledTabs == undefined) {
|
||||
disabledTabs = [
|
||||
{ type: 'static', value: false, fieldType: 'boolean' },
|
||||
{ type: 'static', value: false, fieldType: 'boolean' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
$: tabs = items.map((item) => item.value)
|
||||
let items = $state.raw(
|
||||
tabs.map((tab, index) => {
|
||||
return { value: tab, id: generateRandomString(), originalIndex: index }
|
||||
})
|
||||
)
|
||||
|
||||
$effect.pre(() => {
|
||||
items
|
||||
untrack(() => {
|
||||
tabs = items.map((item) => item.value)
|
||||
})
|
||||
})
|
||||
|
||||
const { app, runnableComponents, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
@@ -149,15 +168,15 @@
|
||||
flipDurationMs: 200,
|
||||
dropTargetStyle: {}
|
||||
}}
|
||||
on:consider={handleConsider}
|
||||
on:finalize={handleFinalize}
|
||||
onconsider={handleConsider}
|
||||
onfinalize={handleFinalize}
|
||||
>
|
||||
{#each items as item, index (item.id)}
|
||||
<div class="border rounded-md p-2 mb-2 bg-surface">
|
||||
<div class="w-full flex flex-row gap-2 items-center relative my-1">
|
||||
<input
|
||||
on:keydown|stopPropagation
|
||||
on:input={(e) => updateItemValue(index, e)}
|
||||
onkeydown={stopPropagation(bubble('keydown'))}
|
||||
oninput={(e) => updateItemValue(index, e)}
|
||||
type="text"
|
||||
bind:value={items[index].value}
|
||||
/>
|
||||
@@ -166,9 +185,9 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col justify-center gap-2">
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div use:dragHandle class="handle w-4 h-4" aria-label="drag-handle">
|
||||
<GripVertical size={16} />
|
||||
</div>
|
||||
|
||||
@@ -4,11 +4,15 @@
|
||||
import InputsSpecEditor from './InputsSpecEditor.svelte'
|
||||
import { slide } from 'svelte/transition'
|
||||
|
||||
export let id: string
|
||||
export let field: RichConfiguration
|
||||
export let index: number
|
||||
interface Props {
|
||||
id: string
|
||||
field: RichConfiguration
|
||||
index: number
|
||||
}
|
||||
|
||||
let disablable = field && !(field?.type === 'static' && field?.value === false)
|
||||
let { id, field = $bindable(), index }: Props = $props()
|
||||
|
||||
let disablable = $state(field && !(field?.type === 'static' && field?.value === false))
|
||||
</script>
|
||||
|
||||
<Toggle
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
}
|
||||
return r
|
||||
})
|
||||
console.log('BAR 2')
|
||||
selectedRunnable = nid
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user