mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-05 00:03:08 +00:00
App menu improvements (#2753)
* fix(frontend): add dropdown menu result + fix splitpanes seperators * fix(frontend): remove useless border * fix(frontend): fix arg enum * fix(frontend): remove useless div * fix(frontend): remove duplicated code * fix(frontend): remove duplicated code * fix(frontend): fix reactivity * fix(frontend): fix reactivity
This commit is contained in:
@@ -1,23 +1,28 @@
|
||||
<script lang="ts">
|
||||
import AutoComplete from 'simple-svelte-autocomplete'
|
||||
import { Pen } from 'lucide-svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export let customValue: boolean
|
||||
export let disabled: boolean
|
||||
export let value: any
|
||||
export let enum_: string[] | undefined
|
||||
export let autofocus: boolean
|
||||
export let defaultValue: string | undefined
|
||||
export let valid: boolean
|
||||
export let disableCustomValue: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let customItems: string[] = []
|
||||
|
||||
function onCreate(newItem: string) {
|
||||
customItems = [...customItems, newItem]
|
||||
|
||||
return newItem
|
||||
}
|
||||
</script>
|
||||
|
||||
<AutoComplete
|
||||
items={enum_ ?? []}
|
||||
items={[...(enum_ ?? []), ...customItems]}
|
||||
bind:selectedItem={value}
|
||||
inputClassName={twMerge(
|
||||
'bg-surface-secondary flex',
|
||||
@@ -32,18 +37,9 @@
|
||||
onFocus={() => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
create
|
||||
{onCreate}
|
||||
{disabled}
|
||||
{autofocus}
|
||||
createText="Press enter to use this non-predefined value"
|
||||
/>
|
||||
|
||||
{#if !disabled && !disableCustomValue}
|
||||
<button
|
||||
class="min-w-min !px-2 items-center text-gray-800 bg-surface-secondary border rounded center-center hover:bg-gray-300 transition-all cursor-pointer"
|
||||
on:click={() => {
|
||||
customValue = !customValue
|
||||
}}
|
||||
title="Custom Value"
|
||||
>
|
||||
<Pen class="text-tertiary" size={14} />
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -188,11 +188,8 @@
|
||||
}
|
||||
|
||||
let redraw = 0
|
||||
|
||||
let itemsLimit = 50
|
||||
|
||||
let customValue = false
|
||||
|
||||
$: validateInput(pattern, value, required)
|
||||
</script>
|
||||
|
||||
@@ -391,11 +388,9 @@
|
||||
}}
|
||||
{defaultValue}
|
||||
{valid}
|
||||
{customValue}
|
||||
{disabled}
|
||||
{autofocus}
|
||||
bind:value={v}
|
||||
disableCustomValue={true}
|
||||
enum_={itemsType?.enum ?? []}
|
||||
/>
|
||||
{:else}
|
||||
@@ -495,7 +490,7 @@
|
||||
{/if}
|
||||
{:else if inputCat == 'enum'}
|
||||
<div class="flex flex-row w-full gap-1">
|
||||
<ArgEnum {defaultValue} {valid} {customValue} {disabled} bind:value {enum_} {autofocus} />
|
||||
<ArgEnum {defaultValue} {valid} {disabled} bind:value {enum_} {autofocus} />
|
||||
</div>
|
||||
{:else if inputCat == 'date'}
|
||||
<DateTimeInput {autofocus} bind:value />
|
||||
|
||||
@@ -27,21 +27,19 @@
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
export let menuItems: (BaseAppComponent & ButtonComponent)[]
|
||||
|
||||
const { app, worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
result: {
|
||||
latestButtonClicked: undefined as string | undefined
|
||||
}
|
||||
})
|
||||
|
||||
const resolvedConfig = initConfig(
|
||||
components['menucomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
const { app, worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
initOutput($worldStore, id, {
|
||||
result: undefined,
|
||||
loading: false
|
||||
})
|
||||
|
||||
//used so that we can count number of outputs setup for first refresh
|
||||
initOutput($worldStore, id, {})
|
||||
|
||||
let beforeIconComponent: any
|
||||
let afterIconComponent: any
|
||||
let css = initCss($app.css?.menucomponent, customCss)
|
||||
@@ -123,17 +121,25 @@
|
||||
{#if menuItems.length > 0}
|
||||
{#each menuItems as actionButton, actionIndex (actionButton?.id)}
|
||||
{#if actionButton.type == 'buttoncomponent'}
|
||||
<AppButton
|
||||
extraKey={'idx' + actionIndex}
|
||||
{render}
|
||||
id={actionButton.id}
|
||||
customCss={actionButton.customCss}
|
||||
configuration={actionButton.configuration}
|
||||
recomputeIds={actionButton.recomputeIds}
|
||||
componentInput={actionButton.componentInput}
|
||||
noWFull={false}
|
||||
isMenuItem={true}
|
||||
/>
|
||||
<div
|
||||
on:pointerup={() => {
|
||||
outputs?.result.set({
|
||||
latestButtonClicked: actionButton.id
|
||||
})
|
||||
}}
|
||||
>
|
||||
<AppButton
|
||||
extraKey={'idx' + actionIndex}
|
||||
{render}
|
||||
id={actionButton.id}
|
||||
customCss={actionButton.customCss}
|
||||
configuration={actionButton.configuration}
|
||||
recomputeIds={actionButton.recomputeIds}
|
||||
componentInput={actionButton.componentInput}
|
||||
noWFull={false}
|
||||
isMenuItem={true}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
@@ -551,7 +551,7 @@
|
||||
class={twMerge(
|
||||
'bg-surface-secondary h-full w-full relative',
|
||||
$appStore.css?.['app']?.['viewer']?.class,
|
||||
'wm-app-viewer z-[100] h-full overflow-visible'
|
||||
'wm-app-viewer h-full overflow-visible'
|
||||
)}
|
||||
style={$appStore.css?.['app']?.['viewer']?.style}
|
||||
>
|
||||
@@ -594,7 +594,7 @@
|
||||
on:scroll={parseScroll}
|
||||
class={classNames(
|
||||
'mx-auto w-full h-full z-50',
|
||||
$appStore.fullscreen ? '' : 'max-w-7xl border-x',
|
||||
$appStore.fullscreen ? '' : 'max-w-7xl',
|
||||
$componentActive ? 'absolute' : 'overflow-auto'
|
||||
)}
|
||||
style={$componentActive ? `top: -${$yTop}px;` : ''}
|
||||
@@ -614,7 +614,7 @@
|
||||
</Pane>
|
||||
{#if $connectingInput?.opened == false && !$componentActive}
|
||||
<Pane bind:size={runnablePanelSize}>
|
||||
<div class="relative h-full w-full z-[100]">
|
||||
<div class="relative h-full w-full">
|
||||
<InlineScriptsPanel />
|
||||
</div>
|
||||
</Pane>
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { GridItem } from '$lib/components/apps/types'
|
||||
import TableActionOutput from './TableActionOutput.svelte'
|
||||
import Output from './Output.svelte'
|
||||
|
||||
export let gridItem: GridItem
|
||||
</script>
|
||||
@@ -9,7 +9,7 @@
|
||||
{#if gridItem.data.type === 'menucomponent' && gridItem.data.menuItems.length > 0}
|
||||
<div class="ml-2 border-l">
|
||||
{#each gridItem.data.menuItems as action, index}
|
||||
<TableActionOutput id={action.id} first={index === 0} />
|
||||
<Output id={action.id} first={index === 0} label="Menu item" />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
+2
-1
@@ -9,9 +9,10 @@
|
||||
|
||||
export let id: string
|
||||
export let first: boolean = false
|
||||
export let label: string
|
||||
</script>
|
||||
|
||||
<OutputHeader renamable={false} {id} name={'Table action'} {first}>
|
||||
<OutputHeader renamable={false} {id} name={label} {first}>
|
||||
<ComponentOutputViewer
|
||||
componentId={id}
|
||||
on:select={({ detail }) => {
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { GridItem } from '$lib/components/apps/types'
|
||||
import TableActionOutput from './TableActionOutput.svelte'
|
||||
import Output from './Output.svelte'
|
||||
|
||||
export let gridItem: GridItem
|
||||
</script>
|
||||
@@ -9,7 +9,7 @@
|
||||
{#if gridItem.data.type === 'tablecomponent' && gridItem.data.actionButtons.length > 0}
|
||||
<div class="ml-2 border-l">
|
||||
{#each gridItem.data.actionButtons as action, index}
|
||||
<TableActionOutput id={action.id} first={index === 0} />
|
||||
<Output id={action.id} first={index === 0} label="Table action" />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -162,7 +162,6 @@
|
||||
bind:inlineScript
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<div class="h-full flex flex-col gap-1">
|
||||
<div class="flex justify-between w-full gap-2 px-2 pt-1 flex-row items-center">
|
||||
{#if name !== undefined}
|
||||
|
||||
@@ -792,7 +792,6 @@ const config = {
|
||||
backgroundColor: lightTheme.border + ' !important',
|
||||
margin: '0 !important',
|
||||
border: 'none !important',
|
||||
zIndex: '1001 !important',
|
||||
'&::after': {
|
||||
backgroundColor: lightTheme.border + ' !important',
|
||||
margin: '0 !important',
|
||||
@@ -803,7 +802,8 @@ const config = {
|
||||
'--splitter-hover-adjustment': '-2px'
|
||||
},
|
||||
'&:hover::after': {
|
||||
opacity: '1'
|
||||
opacity: '1',
|
||||
zIndex: '1001 !important'
|
||||
}
|
||||
},
|
||||
'.dark .splitpanes__splitter': {
|
||||
|
||||
Reference in New Issue
Block a user