diff --git a/frontend/src/lib/components/apps/components/inputs/AppDateInput.svelte b/frontend/src/lib/components/apps/components/inputs/AppDateInput.svelte
index 96d63b89aa..9f2308712f 100644
--- a/frontend/src/lib/components/apps/components/inputs/AppDateInput.svelte
+++ b/frontend/src/lib/components/apps/components/inputs/AppDateInput.svelte
@@ -38,7 +38,7 @@
result: undefined as string | undefined
})
- $: handleDefault(resolvedConfig.defaultValue)
+ $: !value && handleDefault(resolvedConfig.defaultValue)
function formatDate(dateString: string, formatString: string = 'dd.MM.yyyy') {
if (formatString === '') {
@@ -98,7 +98,7 @@
min={resolvedConfig.minDate}
max={resolvedConfig.maxDate}
placeholder="Type..."
- class={twMerge(css?.input?.class, 'wm-date-input')}
+ class={twMerge('windmillapp w-full py-1.5 text-sm px-2', css?.input?.class, 'wm-date-input')}
style={css?.input?.style ?? ''}
/>
{/if}
diff --git a/frontend/src/lib/components/apps/components/inputs/AppDateTimeInput.svelte b/frontend/src/lib/components/apps/components/inputs/AppDateTimeInput.svelte
new file mode 100644
index 0000000000..b12df32600
--- /dev/null
+++ b/frontend/src/lib/components/apps/components/inputs/AppDateTimeInput.svelte
@@ -0,0 +1,151 @@
+
+
+{#each Object.keys(components['datetimeinputcomponent'].initialData.configuration) as key (key)}
+
+{/each}
+
+{#each Object.keys(css ?? {}) as key (key)}
+
+{/each}
+
+
+
+
+
+ {#if inputType === 'date'}
+ {
+ e.stopPropagation()
+ $selectedComponent = [id]
+ }}
+ minDate={resolvedConfig.minDateTime
+ ? formatDate(resolvedConfig.minDateTime, 'yyyy-MM-dd')
+ : undefined}
+ maxDate={resolvedConfig.maxDateTime
+ ? formatDate(resolvedConfig.maxDateTime, 'yyyy-MM-dd')
+ : undefined}
+ on:focus={() => ($selectedComponent = [id])}
+ />
+ {/if}
+
+
diff --git a/frontend/src/lib/components/apps/components/inputs/AppTimeInput.svelte b/frontend/src/lib/components/apps/components/inputs/AppTimeInput.svelte
new file mode 100644
index 0000000000..60a888113f
--- /dev/null
+++ b/frontend/src/lib/components/apps/components/inputs/AppTimeInput.svelte
@@ -0,0 +1,122 @@
+
+
+{#each Object.keys(components['timeinputcomponent'].initialData.configuration) as key (key)}
+
+{/each}
+
+{#each Object.keys(css ?? {}) as key (key)}
+
+{/each}
+
+
+
+
+ ($selectedComponent = [id])}
+ on:pointerdown|stopPropagation={() => ($selectedComponent = [id])}
+ type="time"
+ bind:value
+ min={resolvedConfig.minTime}
+ max={resolvedConfig.maxTime}
+ placeholder="Type..."
+ class={twMerge('windmillapp w-full py-1.5 text-sm px-2', css?.input?.class)}
+ style={css?.input?.style ?? ''}
+ />
+
diff --git a/frontend/src/lib/components/apps/editor/component/Component.svelte b/frontend/src/lib/components/apps/editor/component/Component.svelte
index 60e4f1a7c6..7749183b53 100644
--- a/frontend/src/lib/components/apps/editor/component/Component.svelte
+++ b/frontend/src/lib/components/apps/editor/component/Component.svelte
@@ -71,6 +71,8 @@
import AppS3FileInput from '../../components/inputs/AppS3FileInput.svelte'
import AppAlert from '../../components/display/AppAlert.svelte'
import AppDateSliderInput from '../../components/inputs/AppDateSliderInput.svelte'
+ import AppTimeInput from '../../components/inputs/AppTimeInput.svelte'
+ import AppDateTimeInput from '../../components/inputs/AppDateTimeInput.svelte'
export let component: AppComponent
export let selected: boolean
@@ -494,6 +496,23 @@
customCss={component.customCss}
{render}
/>
+ {:else if component.type === 'timeinputcomponent'}
+
+ {:else if component.type === 'datetimeinputcomponent'}
+
{:else if component.type === 'numberinputcomponent'}
export type PasswordInputComponent = BaseComponent<'passwordinputcomponent'>
export type EmailInputComponent = BaseComponent<'emailinputcomponent'>
export type DateInputComponent = BaseComponent<'dateinputcomponent'>
+export type TimeInputComponent = BaseComponent<'timeinputcomponent'>
+export type DateTimeInputComponent = BaseComponent<'datetimeinputcomponent'>
export type NumberInputComponent = BaseComponent<'numberinputcomponent'>
export type CurrencyComponent = BaseComponent<'currencycomponent'>
export type SliderComponent = BaseComponent<'slidercomponent'>
@@ -291,6 +295,8 @@ export type TypedComponent =
| AgChartsComponentEe
| AlertComponent
| DateSliderComponent
+ | TimeInputComponent
+ | DateTimeInputComponent
export type AppComponent = BaseAppComponent & TypedComponent
@@ -2314,12 +2320,14 @@ This is a paragraph.
minDate: {
type: 'static',
value: '',
- fieldType: 'date'
+ fieldType: 'date',
+ tooltip: 'The minimum date that can be selected. The format is: "yyyy-MM-dd"'
},
maxDate: {
type: 'static',
value: '',
- fieldType: 'date'
+ fieldType: 'date',
+ tooltip: 'The maximum date that can be selected. The format is: "yyyy-MM-dd"'
},
defaultValue: {
type: 'static',
@@ -2330,8 +2338,125 @@ This is a paragraph.
type: 'static',
value: undefined,
fieldType: 'text',
- tooltip: 'See date-fns format for more information',
- documentationLink: 'https://date-fns.org/v1.29.0/docs/format'
+ markdownTooltip: `### Output format
+See date-fns format for more information. By default, it is 'dd.MM.yyyy'
+
+| Format | Result | Description |
+| ----------- | ----------- | ----------- |
+| DD | 01, 02, ..., 31 | Day of the month |
+| D | 1, 2, ..., 31 | Day of the month |
+| MM | 01, 02, ..., 12 | Month |
+| MMM | Jan, Feb, ..., Dec | Month |
+| MMMM | January, February, ..., December | Month |
+| YYYY | 2021, 2022, ... | Year |
+`,
+
+ documentationLink: 'https://date-fns.org/v1.29.0/docs/format',
+ placeholder: 'dd.MM.yyyy'
+ }
+ }
+ }
+ },
+ datetimeinputcomponent: {
+ name: 'Date & Time',
+ icon: CalendarClock,
+ documentationLink: `${documentationBaseUrl}/datetime_input`,
+ dims: '2:1-6:2' as AppComponentDimensions,
+ customCss: {
+ container: { class: '', style: '' }
+ },
+ initialData: {
+ verticalAlignment: 'center',
+ componentInput: undefined,
+ configuration: {
+ displayPresets: {
+ type: 'static',
+ value: false,
+ fieldType: 'boolean',
+ tooltip: 'Display presets to select the date for example, in 1 week, in 1 month, etc.'
+ },
+ minDateTime: {
+ type: 'static',
+ value: '',
+ fieldType: 'datetime',
+ tooltip:
+ 'The minimum date that can be selected. The format is the ISO 8601 format: "yyyy-MM-ddTHH:mm:ss:SSSZ", for example "2021-11-06T23:39:30.000Z", or toISOString() from a Date'
+ },
+ maxDateTime: {
+ type: 'static',
+ value: '',
+ fieldType: 'datetime',
+ tooltip:
+ 'The maximum date that can be selected. The format is the ISO 8601 format: "yyyy-MM-ddTHH:mm:ss:SSSZ", for example "2021-11-06T23:39:30.000Z", or toISOString() from a Date'
+ },
+ outputFormat: {
+ type: 'static',
+ value: undefined,
+ fieldType: 'text',
+ documentationLink: 'https://date-fns.org/v1.29.0/docs/format',
+ placeholder: 'dd.MM.yyyy HH:mm',
+ markdownTooltip: `### Output format
+See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
+
+| Format | Result | Description |
+| ----------- | ----------- | ----------- |
+| DD | 01, 02, ..., 31 | Day of the month |
+| D | 1, 2, ..., 31 | Day of the month |
+| MM | 01, 02, ..., 12 | Month |
+| MMM | Jan, Feb, ..., Dec | Month |
+| MMMM | January, February, ..., December | Month |
+| YYYY | 2021, 2022, ... | Year |
+| HH | 00, 01, ..., 23 | Hours |
+| mm | 00, 01, ..., 59 | Minutes |
+| ss | 00, 01, ..., 59 | Seconds |
+ `
+ },
+ defaultValue: {
+ type: 'static',
+ value: undefined,
+ fieldType: 'datetime'
+ }
+ }
+ }
+ },
+ timeinputcomponent: {
+ name: 'Time',
+ icon: Clock,
+ documentationLink: `${documentationBaseUrl}/time_input`,
+ dims: '2:1-3:1' as AppComponentDimensions,
+ customCss: {
+ input: { class: '', style: '' }
+ },
+ initialData: {
+ verticalAlignment: 'center',
+ componentInput: undefined,
+ configuration: {
+ minTime: {
+ type: 'static',
+ value: '',
+ fieldType: 'time',
+ tooltip:
+ 'The minimum date that can be selected. If the time provided is not valid, it will set the output "validity" to false. The format is: "HH:mm"'
+ },
+ maxTime: {
+ type: 'static',
+ value: '',
+ fieldType: 'time',
+ tooltip:
+ 'The maximum date that can be selected. If the time provided is not valid, it will set the output "validity" to false. The format is: "HH:mm"'
+ },
+ defaultValue: {
+ type: 'static',
+ value: undefined,
+ fieldType: 'time'
+ },
+
+ ['24hFormat']: {
+ type: 'static',
+ value: true,
+ fieldType: 'boolean',
+ tooltip:
+ 'Use 24h format. Will change the format of the output of the component: HH:mm to hh:mm am/pm'
}
}
}
diff --git a/frontend/src/lib/components/apps/editor/component/sets.ts b/frontend/src/lib/components/apps/editor/component/sets.ts
index 2800257481..d69961d027 100644
--- a/frontend/src/lib/components/apps/editor/component/sets.ts
+++ b/frontend/src/lib/components/apps/editor/component/sets.ts
@@ -43,6 +43,8 @@ const inputs: ComponentSet = {
'dateslidercomponent',
'rangecomponent',
'dateinputcomponent',
+ 'timeinputcomponent',
+ 'datetimeinputcomponent',
'fileinputcomponent',
's3fileinputcomponent',
'checkboxcomponent',
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/componentControlUtils.ts b/frontend/src/lib/components/apps/editor/componentsPanel/componentControlUtils.ts
index a1d472fcaf..a4470e2e82 100644
--- a/frontend/src/lib/components/apps/editor/componentsPanel/componentControlUtils.ts
+++ b/frontend/src/lib/components/apps/editor/componentsPanel/componentControlUtils.ts
@@ -105,6 +105,8 @@ export function getComponentControl(type: keyof typeof components): Array('AppViewerContext')
@@ -80,8 +82,8 @@
{#if loading}
{/if}
- {#if tooltip}
-
+ {#if tooltip || markdownTooltip}
+
{tooltip}
{/if}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte
index 05a3ad927f..be517a66b5 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte
@@ -59,6 +59,8 @@
placeholder={meta?.['placeholder']}
customTitle={meta?.['customTitle']}
loading={meta?.['loading']}
+ documentationLink={meta?.['documentationLink']}
+ markdownTooltip={meta?.['markdownTooltip']}
{displayType}
{recomputeOnInputChanged}
{showOnDemandOnlyToggle}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte
index 3fc3e0f38b..9f6c027e4b 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte
@@ -101,6 +101,7 @@
tooltip={config?.['tooltip']}
fileUpload={config?.['fileUpload']}
loading={config?.['loading']}
+ documentationLink={config?.['documentationLink']}
{showOnDemandOnlyToggle}
/>
{/if}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte
index 995ae0e7e1..9557af3a4e 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte
@@ -20,6 +20,7 @@
import AgChartWizard from '$lib/components/wizards/AgChartWizard.svelte'
import DBExplorerWizard from '$lib/components/wizards/DBExplorerWizard.svelte'
import Label from '$lib/components/Label.svelte'
+ import DateTimeInput from '$lib/components/DateTimeInput.svelte'
export let componentInput: StaticInput | undefined
export let fieldType: InputType | undefined = undefined
@@ -42,6 +43,10 @@
{:else if fieldType === 'date'}
+ {:else if fieldType === 'time'}
+
+ {:else if fieldType === 'datetime'}
+
{:else if fieldType === 'boolean'}
{:else if fieldType === 'select' && selectOptions}