Improve handling of time-only fields and fix issue where time-only values were not displayed properly

This commit is contained in:
Andrew Kingston 2024-04-12 09:40:39 +01:00
parent 8598f53816
commit e1245b4cb0
4 changed files with 34 additions and 37 deletions

View File

@ -1,5 +1,6 @@
<script>
import Icon from "../../../Icon/Icon.svelte"
import { getDateDisplayValue } from "../../../helpers"
export let anchor
export let disabled
@ -13,20 +14,7 @@
export let enableTime
export let timeOnly
$: displayValue = getDisplayValue(value, enableTime, timeOnly)
const getDisplayValue = (value, enableTime, timeOnly) => {
if (!value?.isValid()) {
return ""
}
if (timeOnly) {
return value.format("HH:mm")
} else if (!enableTime) {
return value.format("MMMM D YYYY")
} else {
return value.format("MMMM D YYYY, HH:mm")
}
}
$: displayValue = getDateDisplayValue(value, { enableTime, timeOnly })
</script>
<!-- svelte-ignore a11y-no-static-element-interactions -->

View File

@ -7,7 +7,7 @@
import { createEventDispatcher, onMount } from "svelte"
import TimePicker from "./TimePicker.svelte"
import Calendar from "./Calendar.svelte"
import DateTimeInput from "./DateInput.svelte"
import DateInput from "./DateInput.svelte"
import ActionButton from "../../../ActionButton/ActionButton.svelte"
import { parseDate } from "../../../helpers"
@ -68,9 +68,13 @@
}
let newValue = date.toISOString()
// If time only set date component to 2000-01-01
if (timeOnly) {
newValue = `2000-01-01T${newValue.split("T")[1]}`
// Time only fields always ignore timezones, otherwise they make no sense.
// For non-timezone-aware fields, create an ISO 8601 timestamp of the exact
// time picked, without timezone
const offsetForTimezone = (enableTime && ignoreTimezones) || timeOnly
if (offsetForTimezone) {
const offset = new Date().getTimezoneOffset() * 60000
newValue = new Date(date.valueOf() - offset).toISOString().slice(0, -1)
}
// For date-only fields, construct a manual timestamp string without a time
@ -82,13 +86,6 @@
newValue = `${year}-${month}-${day}T00:00:00.000`
}
// For non-timezone-aware fields, create an ISO 8601 timestamp of the exact
// time picked, without timezone
else if (enableTime && ignoreTimezones) {
const offset = new Date().getTimezoneOffset() * 60000
newValue = new Date(date.valueOf() - offset).toISOString().slice(0, -1)
}
dispatch("change", newValue)
}
@ -106,7 +103,7 @@
})
</script>
<DateTimeInput
<DateInput
bind:anchor
{disabled}
{readonly}

View File

@ -117,7 +117,7 @@ export const copyToClipboard = value => {
})
}
export const parseDate = (value, { timeOnly, dateOnly } = {}) => {
export const parseDate = (value, { dateOnly } = {}) => {
// If empty then invalid
if (!value) {
return null
@ -125,7 +125,8 @@ export const parseDate = (value, { timeOnly, dateOnly } = {}) => {
// Certain string values need transformed
if (typeof value === "string") {
if (timeOnly || !isNaN(new Date(`0-${value}`))) {
// Check for time only values
if (!isNaN(new Date(`0-${value}`))) {
value = `0-${value}`
}
@ -146,3 +147,16 @@ export const parseDate = (value, { timeOnly, dateOnly } = {}) => {
// millisecond.
return dayjs(Math.floor(parsedDate.valueOf() / 1000) * 1000)
}
export const getDateDisplayValue = (value, { enableTime, timeOnly }) => {
if (!value?.isValid()) {
return ""
}
if (timeOnly) {
return value.format("HH:mm")
} else if (!enableTime) {
return value.format("MMMM D YYYY")
} else {
return value.format("MMMM D YYYY, HH:mm")
}
}

View File

@ -14,17 +14,15 @@
$: timeOnly = schema?.timeOnly
$: dateOnly = schema?.dateOnly
$: format = timeOnly
? "HH:mm:ss"
: dateOnly
? "MMM D YYYY"
: "MMM D YYYY, HH:mm"
$: editable = focused && !readonly
$: displayValue = getDisplayValue(value, timeOnly, dateOnly, format)
$: displayValue = getDisplayValue(value, timeOnly, dateOnly)
const getDisplayValue = (value, timeOnly, dateOnly, format) => {
const parsedDate = Helpers.parseDate(value, { timeOnly, dateOnly })
return parsedDate?.format(format) || ""
const getDisplayValue = (value, timeOnly, dateOnly) => {
const parsedDate = Helpers.parseDate(value, { dateOnly })
return Helpers.getDateDisplayValue(parsedDate, {
enableTime: !dateOnly,
timeOnly,
})
}
// Ensure we close flatpickr when unselected