|
|
|
|
@ -119,7 +119,7 @@
|
|
|
|
|
@change="[schema.format = $event.target.value, save()]"
|
|
|
|
|
>
|
|
|
|
|
<option
|
|
|
|
|
v-for="format in dateFormats"
|
|
|
|
|
v-for="format in availableDateFormats"
|
|
|
|
|
:key="format"
|
|
|
|
|
:value="format"
|
|
|
|
|
>{{ formatDate(new Date(), format) }}</option>
|
|
|
|
|
@ -248,7 +248,7 @@ export default {
|
|
|
|
|
FieldType,
|
|
|
|
|
IconSettings
|
|
|
|
|
},
|
|
|
|
|
inject: ['t', 'save', 'backgroundColor'],
|
|
|
|
|
inject: ['t', 'save', 'backgroundColor', 'dateFormats'],
|
|
|
|
|
provide () {
|
|
|
|
|
return {
|
|
|
|
|
fieldTypes: ['text', 'number', 'date', 'checkbox', 'radio', 'select']
|
|
|
|
|
@ -318,8 +318,10 @@ export default {
|
|
|
|
|
'space'
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
dateFormats () {
|
|
|
|
|
const formats = [
|
|
|
|
|
availableDateFormats () {
|
|
|
|
|
const formats = this.dateFormats.length
|
|
|
|
|
? [...this.dateFormats]
|
|
|
|
|
: [
|
|
|
|
|
'MM/DD/YYYY',
|
|
|
|
|
'DD/MM/YYYY',
|
|
|
|
|
'YYYY-MM-DD',
|
|
|
|
|
@ -327,11 +329,12 @@ export default {
|
|
|
|
|
'DD.MM.YYYY',
|
|
|
|
|
'MMM D, YYYY',
|
|
|
|
|
'MMMM D, YYYY',
|
|
|
|
|
'MMMM YYYY',
|
|
|
|
|
'D MMM YYYY',
|
|
|
|
|
'D MMMM YYYY'
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
if (Intl.DateTimeFormat().resolvedOptions().timeZone?.includes('Seoul') || navigator.language?.startsWith('ko')) {
|
|
|
|
|
if (!this.dateFormats.length && (Intl.DateTimeFormat().resolvedOptions().timeZone?.includes('Seoul') || navigator.language?.startsWith('ko'))) {
|
|
|
|
|
formats.push('YYYY년 MM월 DD일')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -401,18 +404,47 @@ export default {
|
|
|
|
|
formatDate (date, format) {
|
|
|
|
|
const monthFormats = { M: 'numeric', MM: '2-digit', MMM: 'short', MMMM: 'long' }
|
|
|
|
|
const dayFormats = { D: 'numeric', DD: '2-digit' }
|
|
|
|
|
const yearFormats = { YYYY: 'numeric', YY: '2-digit' }
|
|
|
|
|
const yearFormats = { YYYY: 'numeric', YYY: 'numeric', YY: '2-digit' }
|
|
|
|
|
const hourFormats = { H: 'numeric', HH: '2-digit', h: 'numeric', hh: '2-digit' }
|
|
|
|
|
const minuteFormats = { m: 'numeric', mm: '2-digit' }
|
|
|
|
|
const secondFormats = { s: 'numeric', ss: '2-digit' }
|
|
|
|
|
|
|
|
|
|
const parts = new Intl.DateTimeFormat([], {
|
|
|
|
|
const opts = {
|
|
|
|
|
day: dayFormats[format.match(/D+/)],
|
|
|
|
|
month: monthFormats[format.match(/M+/)],
|
|
|
|
|
year: yearFormats[format.match(/Y+/)]
|
|
|
|
|
}).formatToParts(date)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (format.match(/H+/)) { opts.hour = hourFormats[format.match(/H+/)[0]]; opts.hour12 = false }
|
|
|
|
|
if (format.match(/h+/)) { opts.hour = hourFormats[format.match(/h+/)[0]]; opts.hour12 = true }
|
|
|
|
|
if (/[Aa]/.test(format) && opts.hour12 === undefined) opts.hour12 = true
|
|
|
|
|
if (format.match(/m+/)) opts.minute = minuteFormats[format.match(/m+/)[0]]
|
|
|
|
|
if (format.match(/s+/)) opts.second = secondFormats[format.match(/s+/)[0]]
|
|
|
|
|
if (/z/.test(format)) opts.timeZoneName = 'short'
|
|
|
|
|
|
|
|
|
|
const partTypes = {
|
|
|
|
|
M: 'month',
|
|
|
|
|
D: 'day',
|
|
|
|
|
Y: 'year',
|
|
|
|
|
H: 'hour',
|
|
|
|
|
h: 'hour',
|
|
|
|
|
m: 'minute',
|
|
|
|
|
s: 'second',
|
|
|
|
|
z: 'timeZoneName',
|
|
|
|
|
A: 'dayPeriod',
|
|
|
|
|
a: 'dayPeriod'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return format
|
|
|
|
|
.replace(/D+/, parts.find((p) => p.type === 'day').value)
|
|
|
|
|
.replace(/M+/, parts.find((p) => p.type === 'month').value)
|
|
|
|
|
.replace(/Y+/, parts.find((p) => p.type === 'year').value)
|
|
|
|
|
const parts = new Intl.DateTimeFormat([], opts).formatToParts(date)
|
|
|
|
|
|
|
|
|
|
return format.replace(/MMMM|MMM|MM|M|DD|D|YYYY|YYY|YY|HH|hh|H|h|mm|m|ss|s|A|a|z/g, (token) => {
|
|
|
|
|
const value = parts.find((p) => p.type === partTypes[token[0]])?.value
|
|
|
|
|
|
|
|
|
|
if (token === 'A') return (value || '').toUpperCase()
|
|
|
|
|
if (token === 'a') return (value || '').toLowerCase()
|
|
|
|
|
|
|
|
|
|
return value
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
closeDropdown () {
|
|
|
|
|
this.$el.getRootNode().activeElement.blur()
|
|
|
|
|
|