feat(frontend): Improve app components (#3672)

* fix(frontend): wip

* fix(frontend): wip

* fix(frontend): improve components

* fix(frontend): improve components

* fix(frontend): improve ranges

* fix(frontend): fix build
This commit is contained in:
Faton Ramadani
2024-05-07 18:04:12 +02:00
committed by GitHub
parent 010662d3d0
commit ee2a193958
17 changed files with 169 additions and 148 deletions
+1
View File
@@ -157,4 +157,5 @@
.app-editor-input {
@apply rounded-component border border-gray-300 dark:border-gray-500 focus:border-gray-300 focus:dark:border-gray-500 focus:!ring-1 focus:!ring-blue-300;
@apply placeholder:text-gray-400 dark:placeholder:text-gray-600;
}
@@ -11,7 +11,8 @@
PanelRightOpen,
Table2,
Braces,
Highlighter
Highlighter,
InfoIcon
} from 'lucide-svelte'
import Portal from 'svelte-portal'
import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
@@ -26,7 +27,7 @@
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
import MapResult from './MapResult.svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
import Popover from './Popover.svelte'
export let result: any
export let requireHtmlApproval = false
@@ -304,13 +305,17 @@
<div class="text-tertiary text-xs flex gap-2 z-10 items-center">
<slot name="copilot-fix" />
{#if !disableExpand && !noControls}
<Tooltip
<Popover
documentationLink="https://www.windmill.dev/docs/core_concepts/rich_display_rendering"
customSize="115%"
>
The result renderer in Windmill supports rich display rendering, allowing you to
customize the display format of your results.
</Tooltip>
<svelte:fragment slot="text">
The result renderer in Windmill supports rich display rendering, allowing you to
customize the display format of your results.
</svelte:fragment>
<div class="-mt-1">
<InfoIcon size={16} />
</div>
</Popover>
<button on:click={() => copyToClipboard(toJsonStr(result))} class="-mt-1">
<ClipboardCopy size={16} />
</button>
@@ -255,7 +255,7 @@
{/each}
{#if render}
<div class="relative h-full w-full">
<div class="relative h-full w-full component-wrapper">
<div
on:pointermove={updateRegionOutput}
on:wheel={updateRegionOutput}
@@ -207,17 +207,13 @@
<InitializeComponent {id} />
{#if render}
<div class="relative flex flex-col w-full h-full bg-gray-100">
<div class="relative flex flex-col w-full h-full bg-gray-100 component-wrapper">
{#if source && zoom}
{#if pages?.length}
<div
bind:clientWidth={controlsWidth}
bind:clientHeight={controlsHeight}
class="flex {$mode !== 'preview'
? 'w-[calc(100%-2px)] top-[1px]'
: 'w-full top-0'} {wideView
? 'justify-center gap-14'
: '!justify-between'} overflow-x-auto bg-surface border mx-auto py-1"
class="flex flex-row w-full justify-between overflow-x-auto bg-surface border-b mx-auto py-1"
>
<div class="flex justify-start items-center px-2 text-secondary text-sm">
<Button
@@ -293,15 +289,11 @@
disabled={!doc}
size="xs"
color="light"
variant="border"
title="Download PDF"
aria-label="Download PDF"
btnClasses="!font-medium !px-2"
>
{#if wideView}
<span class="mr-1"> Download </span>
{/if}
<Download size={16} />
<Download size={14} />
</Button>
</div>
</div>
@@ -99,7 +99,7 @@
max={resolvedConfig.maxDate}
placeholder="Type..."
class={twMerge(
'windmillapp w-full py-1.5 text-sm px-2 app-editor-input',
'windmillapp w-full py-1.5 text-sm px-1 app-editor-input',
css?.input?.class,
'wm-date-input'
)}
@@ -20,6 +20,7 @@
export let configuration: RichConfigurations
export let customCss: ComponentCustomCSS<'multiselectcomponent'> | undefined = undefined
export let render: boolean
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
const [floatingRef, floatingContent] = createFloatingActions({
strategy: 'absolute',
@@ -104,7 +105,6 @@
}
let w = 0
let h = 0
let open = false
</script>
@@ -129,68 +129,74 @@
<InitializeComponent {id} />
<AlignWrapper {render} hFull>
<AlignWrapper {render} hFull {verticalAlignment}>
<div
class="w-full h-full"
class="w-full app-editor-input"
on:pointerdown={(e) => {
$selectedComponent = [id]
if (!e.shiftKey) {
e.stopPropagation()
}
selectedComponent.set([id])
}}
use:floatingRef
bind:clientWidth={w}
bind:clientHeight={h}
>
{#if !value || Array.isArray(value)}
<div style={`height:${h}px;`}>
<MultiSelect
bind:outerDiv
outerDivClass={`${resolvedConfig.allowOverflow ? '' : 'h-full'}`}
ulSelectedClass={`${resolvedConfig.allowOverflow ? '' : 'overflow-auto max-h-full'} `}
ulOptionsClass={'p-2 !bg-surface-secondary'}
bind:selected={value}
options={Array.isArray(items) ? items : []}
placeholder={resolvedConfig.placeholder}
allowUserOptions={resolvedConfig.create}
on:change={(event) => {
if (event?.detail?.type === 'removeAll') {
outputs?.result.set([])
} else {
outputs?.result.set([...(value ?? [])])
}
<MultiSelect
bind:outerDiv
outerDivClass={`${resolvedConfig.allowOverflow ? '' : 'h-full'}`}
ulSelectedClass={`${resolvedConfig.allowOverflow ? '' : 'overflow-auto max-h-full'} `}
ulOptionsClass={'p-2 !bg-surface-secondary'}
--sms-border={'none'}
--sms-min-height={'32px'}
--sms-focus-border={'none'}
bind:selected={value}
options={Array.isArray(items) ? items : []}
placeholder={resolvedConfig.placeholder}
allowUserOptions={resolvedConfig.create}
on:change={(event) => {
if (event?.detail?.type === 'removeAll') {
outputs?.result.set([])
} else {
outputs?.result.set([...(value ?? [])])
}
}}
on:open={() => {
$selectedComponent = [id]
open = true
}}
on:close={() => {
open = false
}}
let:option
>
<!-- needed because portal doesn't work for mouseup event en mobile -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="w-full"
on:mouseup|stopPropagation
on:pointerdown|stopPropagation={(e) => {
let newe = new MouseEvent('mouseup')
e.target?.['parentElement']?.dispatchEvent(newe)
}}
on:open={() => {
$selectedComponent = [id]
open = true
}}
on:close={() => {
open = false
}}
let:option
>
<!-- needed because portal doesn't work for mouseup event en mobile -->
{option}
</div>
</MultiSelect>
<Portal>
<div use:floatingContent class="z5000" hidden={!open}>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="w-full"
on:mouseup|stopPropagation
on:pointerdown|stopPropagation={(e) => {
let newe = new MouseEvent('mouseup')
e.target?.['parentElement']?.dispatchEvent(newe)
}}>{option}</div
>
</MultiSelect>
<Portal>
<div use:floatingContent class="z5000" hidden={!open}>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
bind:this={portalRef}
class="multiselect"
style={`min-width: ${w}px;`}
on:click|stopPropagation
/>
</div>
</Portal>
</div>
bind:this={portalRef}
class="multiselect"
style={`min-width: ${w}px;`}
on:click|stopPropagation
/>
</div>
</Portal>
{:else}
Value {value} is not an array
{/if}
@@ -90,7 +90,7 @@
on:pointerdown|stopPropagation={() => ($selectedComponent = [id])}
on:focus={() => ($selectedComponent = [id])}
class={twMerge(
'windmillapp w-full py-1.5 text-sm focus:ring-indigo-100 px-2',
'windmillapp w-full py-1.5 px-2 text-sm app-editor-input',
css?.input?.class ?? '',
'wm-number-input'
)}
@@ -74,6 +74,10 @@
handles.forEach((handle) => (handle.style.cssText = css?.handles?.style ?? ''))
}
}
const format = (v, i, p) => {
return `${v}`
}
</script>
{#each Object.keys(components['rangecomponent'].initialData.configuration) as key (key)}
@@ -99,13 +103,7 @@
<AlignWrapper {render} {verticalAlignment}>
<div class="flex flex-col w-full">
<div class="flex items-center w-full gap-1 px-1">
<span
class={twMerge(css?.limits?.class ?? '', 'font-mono wm-slider-limits')}
style={css?.limits?.style ?? ''}
>
{+(resolvedConfig.min ?? 0)}
</span>
<div class="flex items-center w-full gap-1">
<div
class={twMerge('grow', 'wm-slider-bar')}
style="--range-handle-focus: {'#7e9abd'}; --range-handle: {'#7e9abd'}; {css?.bar?.style ??
@@ -113,45 +111,54 @@
on:pointerdown|stopPropagation
>
<RangeSlider
id="range-slider"
springValues={{ stiffness: 1, damping: 1 }}
bind:slider
bind:values
step={resolvedConfig.step}
min={resolvedConfig.min == undefined ? 0 : +resolvedConfig.min}
max={resolvedConfig.max == undefined ? 1 : +resolvedConfig.max}
range
disabled={resolvedConfig.disabled}
pips
float
first="label"
last="label"
step={resolvedConfig.step ?? 1}
pipstep={(resolvedConfig.axisStep ?? 1) / (resolvedConfig.step ?? 1)}
formatter={format}
/>
<!-- <RangeSlider {step} range min={min ?? 0} max={max ?? 1} bind:values /> -->
</div>
<span
class={twMerge(css?.limits?.class ?? '', 'font-mono wm-slider-limits')}
style={css?.limits?.style ?? ''}
>
{+(resolvedConfig.max ?? 1)}
</span>
</div>
<div class="flex justify-between px-1">
<span
class={twMerge(
'font-mono text-center text-sm font-medium bg-blue-100 text-blue-800 rounded px-2.5 py-0.5',
css?.values?.class ?? '',
'wm-slider-value'
)}
style={css?.values?.style ?? ''}
>
{values[0]}
</span>
<span
class={twMerge(
'font-mono text-center text-sm font-medium bg-blue-100 text-blue-800 rounded px-2.5 py-0.5',
css?.values?.class ?? '',
'wm-slider-value'
)}
style={css?.values?.style ?? ''}
>
{values[1]}
</span>
</div>
</div>
</AlignWrapper>
<style>
:global(#range-slider.rangeSlider) {
font-size: 12px;
text-transform: uppercase;
}
:global(.dark #range-slider.rangeSlider) {
background-color: #3b4252;
}
:global(#range-slider.rangeSlider .rangeHandle) {
width: 2em;
height: 2em;
}
:global(#range-slider.rangeSlider .rangeFloat) {
opacity: 1;
background: transparent;
top: 50%;
transform: translate(-50%, -50%);
}
:global(#range-slider.rangeSlider .rangeNub) {
background-color: #7e9abd;
}
:global(.dark #range-slider.rangeSlider > .rangePips > .pip) {
color: #eeeeee;
}
</style>
@@ -221,6 +221,7 @@
<Select
inAppEditor={true}
--border-radius="0.250rem"
--clear-icon-color="#6b7280"
bind:filterText
on:filter={handleFilter}
on:clear={onClear}
@@ -84,8 +84,6 @@
}
}
let width = 0
const spanClass =
'text-center text-sm font-medium bg-blue-100 text-blue-800 rounded px-2.5 py-0.5'
function computeWidth() {
@@ -99,7 +97,6 @@
span.className = spanClass
span.textContent = maxValue.toString()
document.body.appendChild(span)
width = span?.offsetWidth
document.body.removeChild(span)
}
}
@@ -131,15 +128,7 @@
<InitializeComponent {id} />
<AlignWrapper {render} hFull {verticalAlignment}>
<div
class="flex {resolvedConfig.vertical ? 'flex-col' : ''} items-center w-full h-full gap-1 px-1"
>
<span
class={twMerge(css?.limits?.class, 'font-mono wm-slider-limits')}
style={css?.limits?.style ?? ''}
>
{resolvedConfig.vertical ? +(resolvedConfig?.max ?? 0) : +(resolvedConfig?.min ?? 0)}
</span>
<div class="flex {resolvedConfig.vertical ? 'flex-col' : ''} items-center w-full h-full gap-1">
<div
class={twMerge(
'grow',
@@ -147,40 +136,45 @@
'font-mono wm-slider-bar',
resolvedConfig?.vertical ? 'h-full' : 'w-full'
)}
style={css?.bar?.style}
style="--range-handle-focus: {'#7e9abd'}; --range-handle: {'#7e9abd'}; {css?.bar?.style ??
''}"
on:pointerdown|stopPropagation={() => ($selectedComponent = [id])}
>
<RangeSlider
id="range-slider"
springValues={{ stiffness: 1, damping: 1 }}
vertical={resolvedConfig.vertical}
bind:slider
bind:values
step={resolvedConfig.step}
step={resolvedConfig.step ?? 1}
pipstep={(resolvedConfig.axisStep ?? 1) / (resolvedConfig.step ?? 1)}
min={+(resolvedConfig?.min ?? 0)}
max={+(resolvedConfig?.max ?? 0)}
disabled={resolvedConfig.disabled}
pips
float
first="label"
last="label"
/>
</div>
<span
class={twMerge(css?.limits?.class, 'font-mono wm-slider-limits')}
style={css?.limits?.style ?? ''}
>
{resolvedConfig.vertical ? +(resolvedConfig?.min ?? 0) : +(resolvedConfig?.max ?? 1)}
</span>
<span class="mx-2">
<span
class={twMerge(spanClass, css?.value?.class ?? '', 'font-mono wm-slider-value')}
style={`${css?.value?.style ?? ''} ${width ? `width: ${width}px;` : ''}`}
>
{values[0]}
</span>
</span>
</div>
</AlignWrapper>
<style global>
.rangeSlider.vertical {
height: 80%;
min-height: 10px !important;
<style>
:global(#range-slider.rangeSlider) {
font-size: 12px;
text-transform: uppercase;
}
:global(#range-slider.rangeSlider .rangeHandle) {
width: 2em;
height: 2em;
}
:global(#range-slider.rangeSlider .rangeFloat) {
opacity: 1;
background: transparent;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
@@ -77,6 +77,7 @@
'app-editor-input',
css?.input?.class ?? '',
resolvedConfig.disabled ? 'placeholder:text-gray-400 dark:placeholder:text-gray-600' : '',
'wm-input',
'wm-text-input'
)
@@ -97,7 +97,7 @@
<CurrencyInput
inputClasses={{
formatted: twMerge(
'px-2 w-full py-1.5 windmillapp app-editor-input h-8',
'px-2 text-sm w-full py-1.5 windmillapp app-editor-input',
css?.input?.class,
'wm-currency-input'
),
@@ -437,6 +437,7 @@
id={component.id}
configuration={component.configuration}
customCss={component.customCss}
verticalAlignment={component.verticalAlignment}
{render}
/>
{:else if component.type === 'formcomponent'}
@@ -2051,6 +2051,7 @@ This is a paragraph.
},
initialData: {
componentInput: undefined,
verticalAlignment: 'center',
configuration: {
items: {
type: 'static',
@@ -2248,6 +2249,12 @@ This is a paragraph.
type: 'static',
value: false,
fieldType: 'boolean'
},
axisStep: {
type: 'static',
value: 10,
fieldType: 'number',
tooltip: 'Spread between each number suggestion when using the arrow keys'
}
}
}
@@ -2353,9 +2360,14 @@ This is a paragraph.
type: 'static',
value: false,
fieldType: 'boolean',
tooltip:
'Determine if the slider is disabled, or enabled (only disables interactions, and events)'
},
axisStep: {
type: 'static',
value: 10,
fieldType: 'number',
tooltip: 'Spread between each number suggestion when using the arrow keys'
}
}
}
@@ -127,7 +127,7 @@
`relative center-center flex-col text-center font-medium text-tertiary
border border-dashed border-gray-400 hover:border-blue-500
focus-within:border-blue-300 hover:bg-blue-50 dark:hover:bg-frost-900
duration-200 rounded-lg p-1`,
duration-200 rounded-component p-1`,
c
)}
on:dragover={handleDragOver}
@@ -213,7 +213,7 @@
})
</script>
<div class="w-full h-full p-2 flex flex-col">
<div class="w-full h-full p-0 flex flex-col">
{#if $fileUploads.length > 0 && !forceDisplayUploads}
<div class="border rounded-md flex flex-col gap-1 divide-y h-full w-full p-1">
<div class="flex h-full overflow-y-auto flex-col">
@@ -28,7 +28,6 @@
import WorkflowTimeline from '../WorkflowTimeline.svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
export let lang: Preview['language'] | undefined
export let previewIsLoading = false
export let previewJob: Job | undefined
@@ -148,10 +147,12 @@
Test to see the result here
{/if}
</span>
<Tooltip documentationLink="https://www.windmill.dev/docs/core_concepts/rich_display_rendering">
The result renderer in Windmill supports rich display rendering, allowing you to customize the display format of your results.
<Tooltip
documentationLink="https://www.windmill.dev/docs/core_concepts/rich_display_rendering"
>
The result renderer in Windmill supports rich display rendering, allowing you to
customize the display format of your results.
</Tooltip>
</div>
{/if}
</Pane>