Break out core date parsing utils to share between packages

This commit is contained in:
Andrew Kingston 2024-04-08 08:29:20 +01:00
parent 74ff54eb8a
commit 4afc71c4bf
3 changed files with 39 additions and 40 deletions

View File

@ -9,6 +9,7 @@
import Calendar from "./Calendar.svelte" import Calendar from "./Calendar.svelte"
import DateTimeInput from "./DateInput.svelte" import DateTimeInput from "./DateInput.svelte"
import ActionButton from "../../../ActionButton/ActionButton.svelte" import ActionButton from "../../../ActionButton/ActionButton.svelte"
import { parseDate } from "../../../helpers"
export let id = null export let id = null
export let disabled = false export let disabled = false
@ -30,7 +31,7 @@
let popover let popover
let calendar let calendar
$: parsedValue = parseValue(value) $: parsedValue = parseDate(value)
$: showCalendar = !timeOnly $: showCalendar = !timeOnly
$: showTime = enableTime || timeOnly $: showTime = enableTime || timeOnly
@ -59,28 +60,6 @@
} }
} }
const parseValue = value => {
let parsedDate
// Attempt to parse as a time-only string if required
if (typeof value === "string" && timeOnly) {
parsedDate = dayjs(`0-${value}`)
}
// Attempt to parse as normal if required
if (!parsedDate?.isValid()) {
parsedDate = dayjs(value)
}
if (!parsedDate?.isValid()) {
return null
}
// By rounding to the nearest second we avoid locking up in an endless
// loop in the builder, caused by potentially enriching {{ now }} to every
// millisecond.
return dayjs(Math.floor(parsedDate.valueOf() / 1000) * 1000)
}
const handleChange = date => { const handleChange = date => {
if (!date) { if (!date) {
dispatch("change", null) dispatch("change", null)

View File

@ -1,4 +1,5 @@
import { helpers } from "@budibase/shared-core" import { helpers } from "@budibase/shared-core"
import dayjs from "dayjs"
export const deepGet = helpers.deepGet export const deepGet = helpers.deepGet
@ -115,3 +116,33 @@ export const copyToClipboard = value => {
} }
}) })
} }
export const parseDate = (value, { timeOnly, dateOnly } = {}) => {
// If empty then invalid
if (!value) {
return null
}
// Certain string values need transformed
if (typeof value !== "string") {
if (timeOnly || !isNaN(new Date(`0-${value}`))) {
value = `0-${value}`
}
// If date only, check for cases where we received a UTC string
else if (dateOnly && value.endsWith("Z")) {
value = value.split("Z")[0]
}
}
// Parse value and check for validity
const parsedDate = dayjs(value)
if (!parsedDate.isValid()) {
return null
}
// By rounding to the nearest second we avoid locking up in an endless
// loop in the builder, caused by potentially enriching {{ now }} to every
// millisecond.
return dayjs(Math.floor(parsedDate.valueOf() / 1000) * 1000)
}

View File

@ -1,6 +1,5 @@
<script> <script>
import dayjs from "dayjs" import { CoreDatePicker, Icon, Helpers } from "@budibase/bbui"
import { CoreDatePicker, Icon } from "@budibase/bbui"
import { onMount } from "svelte" import { onMount } from "svelte"
export let value export let value
@ -13,10 +12,7 @@
let datePickerAPI let datePickerAPI
let isOpen let isOpen
// Adding the 0- will turn a string like 00:00:00 into a valid ISO $: timeOnly = schema?.timeOnly
// date, but will make actual ISO dates invalid
$: isTimeValue = !isNaN(new Date(`0-${value}`))
$: timeOnly = isTimeValue || schema?.timeOnly
$: dateOnly = schema?.dateOnly $: dateOnly = schema?.dateOnly
$: format = timeOnly $: format = timeOnly
? "HH:mm:ss" ? "HH:mm:ss"
@ -24,18 +20,11 @@
? "MMM D YYYY" ? "MMM D YYYY"
: "MMM D YYYY, HH:mm" : "MMM D YYYY, HH:mm"
$: editable = focused && !readonly $: editable = focused && !readonly
$: displayValue = getDisplayValue(value, format, timeOnly, isTimeValue) $: displayValue = getDisplayValue(value, timeOnly, dateOnly, format)
const getDisplayValue = (value, format, timeOnly, isTimeValue) => { const getDisplayValue = (value, timeOnly, dateOnly, format) => {
if (!value) { const parsedDate = Helpers.parseDate(value, { timeOnly, dateOnly })
return "" return parsedDate?.format(format) || ""
}
// Parse full date strings
if (!timeOnly || !isTimeValue) {
return dayjs(value).format(format)
}
// Otherwise must be a time string
return dayjs(`0-${value}`).format(format)
} }
// Ensure we close flatpickr when unselected // Ensure we close flatpickr when unselected