feat(frontend): add currency format + add enum autocomplete + fix run… (#2670)

* feat(frontend): add currency format + add enum autocomplete + fix runs page layout

* feat(frontend): use ArgEnum for array when using enums

* Fix currencies

* feat(frontend): fix currency input

* feat(frontend): fix multiselect

* feat(frontend): fix multiselect
This commit is contained in:
Faton Ramadani
2023-11-25 10:16:06 +01:00
committed by GitHub
parent f1c8a47155
commit ea888f5f78
8 changed files with 134 additions and 56 deletions
+28 -31
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import AutoComplete from 'simple-svelte-autocomplete'
import { Pen } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import { createEventDispatcher, onMount } from 'svelte'
import { twMerge } from 'tailwind-merge'
export let customValue: boolean
@@ -10,41 +11,37 @@
export let autofocus: boolean
export let defaultValue: string | undefined
export let valid: boolean
export let disableCustomValue: boolean = false
let autoCompleteItems = enum_ ?? []
const dispatch = createEventDispatcher()
onMount(() => {
autoCompleteItems = enum_ ?? []
})
</script>
{#if !customValue}
<select
on:focus={(e) => {
dispatch('focus')
}}
{disabled}
class="px-6"
bind:value
>
{#each enum_ ?? [] as e}
<option>{e}</option>
{/each}
</select>
{:else}
<!-- svelte-ignore a11y-autofocus -->
<input
{autofocus}
on:focus
type="text"
class={twMerge(
'bg-surface-secondary',
valid
? ''
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'
)}
placeholder={defaultValue ?? ''}
bind:value
/>
{/if}
<AutoComplete
items={autoCompleteItems}
bind:selectedItem={value}
inputClassName={twMerge(
'bg-surface-secondary flex',
valid
? ''
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'
)}
value={value ?? defaultValue}
hideArrow={true}
dropdownClassName="!text-sm !py-2 !rounded-sm !border-gray-200 !border !shadow-md"
className="w-full"
onFocus={() => {
dispatch('focus')
}}
{disabled}
{autofocus}
/>
{#if !disabled}
{#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={() => {
+56 -21
View File
@@ -26,6 +26,8 @@
import ArrayTypeNarrowing from './ArrayTypeNarrowing.svelte'
import DateTimeInput from './DateTimeInput.svelte'
import S3FilePicker from './S3FilePicker.svelte'
import CurrencyInput from './apps/components/inputs/currency/CurrencyInput.svelte'
import Label from './Label.svelte'
export let label: string = ''
export let value: any
@@ -234,6 +236,9 @@
{#if type == 'array'}
<ArrayTypeNarrowing bind:itemsType />
<Label label="Display using multiselect">
<Toggle bind:checked={extra.multiselect} />
</Label>
{:else if (type == 'string' && format != 'date-time') || ['number', 'object'].includes(type ?? '')}
<div class="p-2 my-1 text-xs border-solid border border-gray-200 rounded-lg">
<div class="w-min">
@@ -263,7 +268,12 @@
bind:contentEncoding
/>
{:else if type == 'number'}
<NumberTypeNarrowing bind:min={extra['min']} bind:max={extra['max']} />
<NumberTypeNarrowing
bind:min={extra['min']}
bind:max={extra['max']}
bind:currency={extra['currency']}
bind:currencyLocale={extra['currencyLocale']}
/>
{:else if type == 'object'}
<ObjectTypeNarrowing bind:format />
{/if}
@@ -293,20 +303,34 @@
</div>
{:else if extra['seconds'] !== undefined}
<SecondsInput bind:seconds={value} on:focus />
{:else}
<input
{autofocus}
on:focus
{disabled}
type="number"
class={valid
? ''
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
placeholder={defaultValue ?? ''}
{:else if extra?.currency}
<CurrencyInput
inputClasses={{
formatted: twMerge('px-2 w-full py-1.5 text-black'),
wrapper: 'w-full windmillapp',
formattedZero: twMerge('text-black')
}}
style="color:black;"
bind:value
min={extra['min']}
max={extra['max']}
currency={extra?.currency}
locale={extra?.currencyLocale ?? 'en-US'}
/>
{:else}
<div class="relative w-full">
<input
{autofocus}
on:focus
{disabled}
type="number"
class={valid
? ''
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
placeholder={defaultValue ?? ''}
bind:value
min={extra['min']}
max={extra['max']}
/>
</div>
{/if}
{:else if inputCat == 'boolean'}
<Toggle
@@ -333,6 +357,15 @@
selectedOptionsDraggable={true}
/>
</div>
{:else if extra.multiselect}
<div class="items-start">
<Multiselect
{disabled}
bind:selected={value}
options={itemsType?.enum ?? []}
selectedOptionsDraggable={true}
/>
</div>
{:else}
<div class="w-full">
{#key redraw}
@@ -352,17 +385,19 @@
{:else if itemsType?.type == 'object'}
<JsonEditor code={JSON.stringify(v, null, 2)} bind:value={v} />
{:else if Array.isArray(itemsType?.enum)}
<select
on:focus={(e) => {
<ArgEnum
on:focus={() => {
dispatch('focus')
}}
class="px-6"
{defaultValue}
{valid}
{customValue}
{disabled}
{autofocus}
bind:value={v}
>
{#each itemsType?.enum ?? [] as e}
<option>{e}</option>
{/each}
</select>
disableCustomValue={true}
enum_={itemsType?.enum ?? []}
/>
{:else}
<input type="text" bind:value={v} id="arg-input-array" />
{/if}
@@ -15,6 +15,7 @@
import LightweightResourcePicker from './LightweightResourcePicker.svelte'
import LightweightObjectResourceInput from './LightweightObjectResourceInput.svelte'
import DateTimeInput from './DateTimeInput.svelte'
import CurrencyInput from './apps/components/inputs/currency/CurrencyInput.svelte'
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
export let label: string = ''
@@ -181,6 +182,18 @@
<span>{extra['max']}</span>
<span class="mx-2"><Badge large color="blue">{value}</Badge></span>
</div>
{:else if extra?.currency}
<CurrencyInput
inputClasses={{
formatted: twMerge('px-2 w-full py-1.5 text-black'),
wrapper: 'w-full windmillapp',
formattedZero: twMerge('text-black')
}}
style="color:black;"
bind:value
currency={extra?.currency}
locale={extra?.currencyLocale ?? 'en-US'}
/>
{:else}
<input
on:focus={(e) => {
@@ -350,6 +363,15 @@
placeholder={defaultValue ?? ''}
bind:value
/>
{:else if inputCat == 'currency'}
<input
type="number"
class={valid
? ''
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-3'}
placeholder={defaultValue ?? ''}
bind:value
/>
{:else if inputCat == 'string'}
<div class="flex flex-col w-full">
<div class="flex flex-row w-full items-center justify-between">
@@ -1,8 +1,12 @@
<script lang="ts">
import Label from './Label.svelte'
import Toggle from './Toggle.svelte'
import { selectOptions } from './apps/editor/component'
export let min: number | undefined
export let max: number | undefined
export let currency: string | undefined
export let currencyLocale: string | undefined
let minChecked: boolean = min != undefined
let maxChecked: boolean = max != undefined
@@ -19,4 +23,20 @@
<Toggle bind:checked={maxChecked} options={{ right: 'max' }} />
<input type="number" bind:value={max} disabled={!maxChecked} />
</div>
<Label label="Currency">
<select class="mt-1" bind:value={currency}>
<option value={undefined}> No currency </option>
{#each selectOptions.currencyOptions as c}
<option value={c}>{c}</option>
{/each}
</select>
</Label>
<Label label="Currency locale">
<select class="mt-1" bind:value={currencyLocale}>
<option value={undefined}> No locale </option>
{#each selectOptions.localeOptions as c}
<option value={c}>{c}</option>
{/each}
</select>
</Label>
</div>
@@ -27,7 +27,7 @@
'date-time'
// 'duration',
// 'ipv6',
// 'jsonpointer'
// 'jsonpointer',
]
$: format =
@@ -40,6 +40,7 @@
pattern = '^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$'
}
}
function add() {
enum_ = enum_ ? enum_.concat('') : ['']
}
@@ -123,7 +123,7 @@
<div class="whitespace-nowrap text-xs font-semibold">
{#if job.script_path}
<div class="flex flex-row gap-1 items-center">
<a href="/run/{job.id}?workspace={job.workspace_id}" class="truncate w-8/12">
<a href="/run/{job.id}?workspace={job.workspace_id}" class="truncate w-30">
{job.script_path}
</a>
<Button
+3
View File
@@ -337,6 +337,7 @@ export type InputCat =
| 'object'
| 'sql'
| 'yaml'
| 'currency'
export function setInputCat(
type: string | undefined,
@@ -367,6 +368,8 @@ export function setInputCat(
return 'base64'
} else if (type == 'string' && format == 'email') {
return 'email'
} else if (type == 'string' && format == 'currency') {
return 'currency'
} else {
return 'string'
}
@@ -626,7 +626,7 @@
your own runs or runs of groups you belong to unless you are an admin.
</Tooltip>
</div>
<div class="hidden xl:block">
<div class="hidden 2xl:block">
<RunsFilter
bind:isSkipped
bind:user
@@ -644,7 +644,7 @@
{paths}
/>
</div>
<div class="xl:hidden">
<div class="block 2xl:hidden">
<MobileFilters>
<svelte:fragment slot="filters">
<span class="text-xs font-semibold leading-6">Filters</span>