mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 00:02:19 +00:00
feat(frontend): Add date format (#3675)
* feat(frontend): Add date format * feat(frontend): Add date format * feat(frontend): add missing case * feat(frontend): add date format * fix(frontend): added missing tooltip + added default value to the date component
This commit is contained in:
@@ -39,6 +39,7 @@ export interface SchemaProperty {
|
||||
showExpr?: string
|
||||
password?: boolean
|
||||
order?: string[]
|
||||
dateFormat?: string
|
||||
}
|
||||
|
||||
export interface ModalSchemaProperty {
|
||||
@@ -61,6 +62,7 @@ export interface ModalSchemaProperty {
|
||||
customErrorMessage?: string
|
||||
showExpr?: string
|
||||
password?: boolean
|
||||
dateFormat?: string
|
||||
}
|
||||
|
||||
export function modalToSchema(schema: ModalSchemaProperty): SchemaProperty {
|
||||
@@ -82,7 +84,8 @@ export function modalToSchema(schema: ModalSchemaProperty): SchemaProperty {
|
||||
currencyLocale: schema.currencyLocale,
|
||||
multiselect: schema.multiselect,
|
||||
showExpr: schema.showExpr,
|
||||
password: schema.password
|
||||
password: schema.password,
|
||||
dateFormat: schema.dateFormat
|
||||
}
|
||||
}
|
||||
export type Schema = {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import ArgEnum from './ArgEnum.svelte'
|
||||
import ArrayTypeNarrowing from './ArrayTypeNarrowing.svelte'
|
||||
import DateTimeInput from './DateTimeInput.svelte'
|
||||
import DateInput from './DateInput.svelte'
|
||||
import S3FilePicker from './S3FilePicker.svelte'
|
||||
import CurrencyInput from './apps/components/inputs/currency/CurrencyInput.svelte'
|
||||
import FileUpload from './common/fileUpload/FileUpload.svelte'
|
||||
@@ -290,6 +291,7 @@
|
||||
bind:minRows={extra['minRows']}
|
||||
bind:disableCreate={extra['disableCreate']}
|
||||
bind:disableVariablePicker={extra['disableVariablePicker']}
|
||||
bind:dateFormat={extra['dateFormat']}
|
||||
/>
|
||||
{:else if type == 'number' || type == 'integer'}
|
||||
<NumberTypeNarrowing
|
||||
@@ -312,6 +314,7 @@
|
||||
<pre class="font-main whitespace-normal">{description}</pre>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex space-x-1">
|
||||
{#if inputCat == 'number'}
|
||||
{#if extra['min'] != undefined && extra['max'] != undefined}
|
||||
@@ -599,7 +602,11 @@
|
||||
/>
|
||||
</div>
|
||||
{:else if inputCat == 'date'}
|
||||
<DateTimeInput useDropdown {autofocus} bind:value />
|
||||
{#if format === 'date'}
|
||||
<DateInput {autofocus} bind:value dateFormat={extra?.['dateFormat']} />
|
||||
{:else}
|
||||
<DateTimeInput useDropdown {autofocus} bind:value />
|
||||
{/if}
|
||||
{:else if inputCat == 'sql' || inputCat == 'yaml'}
|
||||
<div class="border my-1 mb-4 w-full border-primary">
|
||||
<SimpleEditor
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { format, isValid } from 'date-fns'
|
||||
|
||||
export let value: string | undefined = undefined
|
||||
export let autofocus: boolean | null = false
|
||||
export let minDate: string | undefined = undefined
|
||||
export let maxDate: string | undefined = undefined
|
||||
export let dateFormat: string | undefined = 'dd-MM-yyyy'
|
||||
|
||||
let date: string | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function updateValue(newDate: string | undefined) {
|
||||
if (newDate && isValid(new Date(newDate))) {
|
||||
if (dateFormat === undefined) {
|
||||
dateFormat = 'dd-MM-yyyy'
|
||||
}
|
||||
|
||||
try {
|
||||
let dateFromValue: Date | undefined = newDate ? new Date(newDate) : undefined
|
||||
|
||||
if (dateFromValue === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const parsedDate = format(dateFromValue, dateFormat)
|
||||
value = parsedDate
|
||||
|
||||
dispatch('change', value)
|
||||
} catch (error) {
|
||||
console.error('Failed to parse date:', error)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let randomId = 'datetarget-' + Math.random().toString(36).substring(7)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-row gap-1 items-center w-full" id={randomId} on:pointerdown on:focus>
|
||||
<input
|
||||
type="date"
|
||||
bind:value={date}
|
||||
{autofocus}
|
||||
class="!w-full app-editor-input"
|
||||
min={minDate}
|
||||
max={maxDate}
|
||||
on:change={() => {
|
||||
if (date) {
|
||||
updateValue(date)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -2,7 +2,7 @@
|
||||
export let label: string | undefined = undefined
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class={$$props.class}>
|
||||
<div class="flex flex-row justify-between items-center w-full">
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<span class="text-secondary text-sm leading-6">{label}</span>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import LightweightResourcePicker from './LightweightResourcePicker.svelte'
|
||||
import LightweightObjectResourceInput from './LightweightObjectResourceInput.svelte'
|
||||
import DateTimeInput from './DateTimeInput.svelte'
|
||||
import DateInput from './DateInput.svelte'
|
||||
import CurrencyInput from './apps/components/inputs/currency/CurrencyInput.svelte'
|
||||
import Multiselect from 'svelte-multiselect'
|
||||
import Password from './Password.svelte'
|
||||
@@ -395,7 +396,11 @@
|
||||
{/each}
|
||||
</select>
|
||||
{:else if inputCat == 'date'}
|
||||
<DateTimeInput bind:value />
|
||||
{#if format === 'date'}
|
||||
<DateInput bind:value dateFormat={extra['dateFormat']} />
|
||||
{:else}
|
||||
<DateTimeInput useDropdown bind:value />
|
||||
{/if}
|
||||
{:else if inputCat == 'base64'}
|
||||
<div class="flex flex-col my-6 w-full">
|
||||
<input
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
}
|
||||
: undefined,
|
||||
showExpr: schema.showExpr,
|
||||
password: schema.password
|
||||
password: schema.password,
|
||||
dateFormat: schema.format
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +135,7 @@
|
||||
property.items = undefined
|
||||
property.showExpr = undefined
|
||||
property.password = undefined
|
||||
property.dateFormat = undefined
|
||||
drawer.closeDrawer()
|
||||
}
|
||||
|
||||
@@ -221,6 +223,7 @@
|
||||
property.currencyLocale = undefined
|
||||
property.multiselect = undefined
|
||||
property.password = undefined
|
||||
property.dateFormat = undefined
|
||||
if (argType == 'array') {
|
||||
property.items = { type: 'string' }
|
||||
} else {
|
||||
@@ -286,6 +289,7 @@
|
||||
bind:enum_={property.enum_}
|
||||
bind:contentEncoding={property.contentEncoding}
|
||||
bind:password={property.password}
|
||||
bind:dateFormat={property.dateFormat}
|
||||
noExtra
|
||||
/>
|
||||
{:else if property.selectedType == 'array'}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Label from './Label.svelte'
|
||||
import RadioButton from './RadioButton.svelte'
|
||||
import ResourceTypePicker from './ResourceTypePicker.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import Tooltip from './Tooltip.svelte'
|
||||
import { Button } from './common'
|
||||
import Alert from './common/alert/Alert.svelte'
|
||||
import ClearableInput from './common/clearableInput/ClearableInput.svelte'
|
||||
import RegexGen from './copilot/RegexGen.svelte'
|
||||
|
||||
export let pattern: string | undefined
|
||||
@@ -16,6 +19,7 @@
|
||||
export let disableVariablePicker: boolean | undefined = false
|
||||
export let password: boolean = false
|
||||
export let noExtra = false
|
||||
export let dateFormat: string | undefined
|
||||
|
||||
let kind: 'none' | 'pattern' | 'enum' | 'resource' | 'format' | 'base64' = computeKind()
|
||||
let patternStr: string = pattern ?? ''
|
||||
@@ -30,7 +34,8 @@
|
||||
'yaml',
|
||||
'sql',
|
||||
// 'time',
|
||||
'date-time'
|
||||
'date-time',
|
||||
'date'
|
||||
// 'duration',
|
||||
// 'ipv6',
|
||||
// 'jsonpointer',
|
||||
@@ -77,6 +82,11 @@
|
||||
}
|
||||
return 'none'
|
||||
}
|
||||
const presetOptions = [
|
||||
{ label: 'ISO Format', format: 'yyyy-MM-dd' },
|
||||
{ label: 'US Format', format: 'MM/dd/yyyy' },
|
||||
{ label: 'EU Format', format: 'dd/MM/yyyy' }
|
||||
]
|
||||
</script>
|
||||
|
||||
<RadioButton
|
||||
@@ -200,6 +210,32 @@
|
||||
<option value={f}>{f}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
{#if format == 'date'}
|
||||
<div class="mt-1" />
|
||||
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<Label label="Date format passed to script" class="col-span-2">
|
||||
<svelte:fragment slot="header">
|
||||
<Tooltip light>
|
||||
Setting the date output format will allow you to specify how the date will be passed to
|
||||
the script.
|
||||
</Tooltip>
|
||||
</svelte:fragment>
|
||||
<ClearableInput type="text" bind:value={dateFormat} placeholder="yyyy-MM-dd" />
|
||||
</Label>
|
||||
<Label label="Presets">
|
||||
<select
|
||||
bind:value={dateFormat}
|
||||
disabled={dateFormat ? !presetOptions.map((f) => f.format).includes(dateFormat) : false}
|
||||
>
|
||||
{#each presetOptions as f}
|
||||
<option value={f.format}>{f.label}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</Label>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if kind == 'none'}
|
||||
{#if !noExtra}
|
||||
<label
|
||||
|
||||
@@ -2478,10 +2478,10 @@ This is a paragraph.
|
||||
},
|
||||
outputFormat: {
|
||||
type: 'static',
|
||||
value: undefined,
|
||||
value: 'yyyy-MM-dd',
|
||||
fieldType: 'text',
|
||||
markdownTooltip: `### Output format
|
||||
See date-fns format for more information. By default, it is 'dd.MM.yyyy'
|
||||
See date-fns format for more information. By default, it is 'yyyy-MM-dd'
|
||||
|
||||
| Format | Result | Description |
|
||||
| ----------- | ----------- | ----------- |
|
||||
@@ -2494,7 +2494,7 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy'
|
||||
`,
|
||||
|
||||
documentationLink: 'https://date-fns.org/v2.30.0/docs/format',
|
||||
placeholder: 'dd.MM.yyyy'
|
||||
placeholder: 'yyyy-MM-dd'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +72,10 @@ export function argSigToJsonSchemaType(
|
||||
delete oldS[prop]
|
||||
}
|
||||
}
|
||||
} else if (oldS.format == 'date-time' && newS.format != 'date-time') {
|
||||
delete oldS.format
|
||||
} else if ((oldS.format == 'date' || oldS.format === 'date-time') && newS.format == 'string') {
|
||||
newS.format = oldS.format
|
||||
} else if (newS.format == 'date-time' && oldS.format == 'date') {
|
||||
newS.format = 'date'
|
||||
} else if (oldS.items?.type != newS.items?.type) {
|
||||
delete oldS.items
|
||||
}
|
||||
|
||||
@@ -400,6 +400,8 @@ export function setInputCat(
|
||||
return 'enum'
|
||||
} else if (type == 'string' && format == 'date-time') {
|
||||
return 'date'
|
||||
} else if (type == 'string' && format == 'date') {
|
||||
return 'date'
|
||||
} else if (type == 'string' && format == 'sql') {
|
||||
return 'sql'
|
||||
} else if (type == 'string' && format == 'yaml') {
|
||||
|
||||
Reference in New Issue
Block a user