1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-21 23:37:55 +00:00
bramw_baserow/web-frontend/modules/database/mixins/dateField.js
2024-06-28 11:40:39 +02:00

215 lines
6.4 KiB
JavaScript

import moment from '@baserow/modules/core/moment'
import {
getCellTimezoneAbbr,
getDateHumanReadableFormat,
getDateMomentFormat,
getFieldTimezone,
getTimeHumanReadableFormat,
getTimeMomentFormat,
} from '@baserow/modules/database/utils/date'
const DATE_PICKER_FORMAT = 'YYYY-MM-DD'
/**
* 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: '',
pickerDate: '',
time: '',
momentDate: null,
}
},
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}|${this.field.date_force_timezone}`
},
fieldDateFormat() {
return getDateMomentFormat(this.field.date_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: {
updateFormattedDateValue() {
this.pickerDate = this.momentDate.format(DATE_PICKER_FORMAT)
this.date = this.momentDate.format(this.fieldDateFormat)
},
updateFormattedTimeValue() {
const timeFormat = getTimeMomentFormat(this.field.date_time_format)
this.time = this.momentDate.format(timeFormat)
},
/**
* 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 dateFormats = [DATE_PICKER_FORMAT, this.fieldDateFormat]
const newDate = moment.utc(value, dateFormats, true)
const timezone = getFieldTimezone(field)
// default to now if no time is set
const now = moment.utc()
if (timezone !== null) {
newDate.tz(timezone, true)
now.tz(timezone)
}
if (newDate.isValid()) {
const momentDate = this.momentDate || now
newDate.set({
hour: momentDate.hour(),
minute: momentDate.minute(),
second: momentDate.second(),
})
// needed again to be able to format correctly the moment date
// composed by the date and time parts separately
if (timezone !== null) {
newDate.tz(timezone)
}
this.updateCopy(field, newDate)
this.updateFormattedDateValue()
} else {
this.updateCopy(field, null)
}
},
/**
* 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, ['hh:mm a', 'HH:mm'], true)
const timezone = getFieldTimezone(field)
if (timezone !== null) {
newTime.tz(timezone, true)
}
if (newTime.isValid()) {
if (this.momentDate !== null) {
newTime.set({
year: this.momentDate.year(),
month: this.momentDate.month(),
date: this.momentDate.date(),
})
// needed again to be able to format correctly the moment date
// composed by the date and time parts separately
if (timezone !== null) {
newTime.tz(timezone)
}
}
this.updateCopy(field, newTime)
this.updateFormattedTimeValue()
} else {
this.time = value
}
},
/**
* When the user uses the datepicker 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) {
this.updateDate(field, moment.utc(value).format(DATE_PICKER_FORMAT))
},
/**
* 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, newMomentDate) {
if (newMomentDate === null) {
this.copy = null
this.momentDate = null
} else {
this.momentDate = newMomentDate
this.copy = field.date_include_time
? this.momentDate.format()
: this.momentDate.format('YYYY-MM-DD')
}
},
/**
* Updates the date and time data by converting the value to the correct formats.
*/
setDateAndTime(field, value) {
if (value === null) {
this.momentDate = null
this.date = this.time = this.pickerDate = ''
} else {
const timezone = getFieldTimezone(field)
this.momentDate = moment.utc(value, moment.ISO_8601, true)
if (timezone) {
this.momentDate.tz(timezone)
}
this.updateFormattedDateValue()
this.updateFormattedTimeValue()
}
},
getCellTimezoneAbbr(field, value, force) {
return getCellTimezoneAbbr(field, value, { force })
},
/**
* 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()
},
},
}