import moment from '@baserow/modules/core/moment' import { getDateMomentFormat, getTimeMomentFormat, getDateHumanReadableFormat, getTimeHumanReadableFormat, } from '@baserow/modules/database/utils/date' /** * Mixin that introduces methods for the date field. This can both be used for a row * and grid view field. */ export default { data() { return { date: '', time: '', } }, computed: { /** * We need to watch the value and the date/time formats. This can easily be done * with a computed property. */ valueAndFormats() { return `${this.value}|${this.field.date_format}|${this.field.date_time_format}` }, }, watch: { /** * When the value or one of the date formats changes we need to update the date * and time data with the correct values. This is because the date and time data * are directly visible to the user and not the value like most other fields. */ valueAndFormats() { if (!this.editing) { this.setDateAndTime(this.field, this.value) } }, }, created() { this.setDateAndTime(this.field, this.value) }, methods: { /** * When the date part is updated we also need to update the copy data which * contains the whole date(time) in the correct format. The copy contains the * value that is actually going to be saved. */ updateDate(field, value) { const dateFormat = getDateMomentFormat(field.date_format) const newDate = moment.utc(value, dateFormat) this.updateCopy( field, { year: newDate.year(), month: newDate.month(), date: newDate.date(), }, newDate ) }, /** * When the time part is updated we also need to update the copy data which * contains the whole date(time) in the correct format. The copy contains the * value that is actually going to be saved. */ updateTime(field, value) { const newTime = moment.utc(value, ['h:m a', 'H:m']) this.updateCopy( field, { hour: newTime.hour(), minute: newTime.minute(), second: 0, }, newTime ) }, /** * When the user uses the datapicker to choose a date, we also need to update * date data and the copy so that the correct date is visible for the user. */ chooseDate(field, value) { const dateFormat = getDateMomentFormat(field.date_format) value = moment.utc(value).format(dateFormat) this.date = value this.updateDate(field, value) }, /** * When the user uses the time context to choose a time, we also need to update * time data and the copy so that the correct time is visible for the user. */ chooseTime(field, value) { this.updateTime(field, value) this.time = value }, /** * A helper method that allows updating the copy data by only changing certain * properties of a datetime. For example only the month could be updated. */ updateCopy(field, values, newDate) { if (!newDate.isValid()) { return } const existing = moment.utc(this.copy || undefined).seconds(0) existing.set(values) let newValue = existing.format() if (!field.date_include_time) { newValue = existing.format('YYYY-MM-DD') } this.copy = newValue }, /** * Updates the date and time data by converting the value to the correct formats. */ setDateAndTime(field, value) { if (value === null) { this.date = '' this.time = '' return } const existing = moment.utc(value || undefined).seconds(0) const dateFormat = getDateMomentFormat(this.field.date_format) const timeFormat = getTimeMomentFormat(this.field.date_time_format) this.date = existing.format(dateFormat) this.time = existing.format(timeFormat) }, /** * Returns a human readable date placeholder of the format for the input. */ getDatePlaceholder(field) { return this.$t( 'humanDateFormat.' + getDateHumanReadableFormat(field.date_format) ) }, /** * Returns a human readable time placeholder of the format for the input. */ getTimePlaceholder(field) { return getTimeHumanReadableFormat(field.date_time_format) }, /** * When the user focuses on one of the inputs the related context menu must * also be opened. */ focus(context, event) { context.toggle(event.currentTarget, 'bottom', 'left', 0) }, /** * When the user blurs one of the inputs the related context menu must also be * hidden. */ blur(context, event) { context.hide() }, }, }