统一预订事项日期选择控件
This commit is contained in:
1 parent
fb980c6814
commit
434afeb7c5
8 files changed
+315
-271
No files matched your search
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<DatePicker
|
||||
v-model="dateModel"
|
||||
:input-id="inputId"
|
||||
class="localized-date-picker"
|
||||
date-format="yy-mm-dd"
|
||||
:placeholder="placeholder"
|
||||
:input-class="inputClass"
|
||||
:pt="datePickerPt"
|
||||
:invalid="invalid"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
show-icon
|
||||
icon-display="input"
|
||||
append-to="body"
|
||||
:panel-class="panelClass"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DatePicker from 'primevue/datepicker'
|
||||
import { usePrimeVue } from 'primevue/config'
|
||||
import { computed, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import {
|
||||
formatDatePickerValue,
|
||||
normalizeDatePickerLocale,
|
||||
parseDatePickerValue,
|
||||
primeVueDatePickerLocales,
|
||||
} from '@/utils/localizedDatePicker'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
modelValue: string
|
||||
inputId: string
|
||||
name?: string
|
||||
testId: string
|
||||
panelTestId?: string
|
||||
placeholder?: string
|
||||
inputClass?: string | Record<string, boolean>
|
||||
invalid?: boolean
|
||||
describedBy?: string
|
||||
disabled?: boolean
|
||||
required?: boolean
|
||||
panelClass?: string
|
||||
}>(), {
|
||||
name: undefined,
|
||||
panelTestId: undefined,
|
||||
placeholder: '',
|
||||
inputClass: undefined,
|
||||
invalid: false,
|
||||
describedBy: undefined,
|
||||
disabled: false,
|
||||
required: false,
|
||||
panelClass: 'localized-date-picker-panel',
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string]
|
||||
}>()
|
||||
|
||||
const { locale } = useI18n()
|
||||
const primeVue = usePrimeVue()
|
||||
|
||||
const dateModel = computed<Date | null>({
|
||||
get: () => parseDatePickerValue(props.modelValue),
|
||||
set: (value) => {
|
||||
emit('update:modelValue', formatDatePickerValue(value))
|
||||
},
|
||||
})
|
||||
|
||||
const datePickerPt = computed(() => ({
|
||||
pcInputText: {
|
||||
root: {
|
||||
name: props.name,
|
||||
'data-testid': props.testId,
|
||||
lang: locale.value,
|
||||
'aria-invalid': props.invalid ? 'true' : undefined,
|
||||
'aria-describedby': props.describedBy,
|
||||
},
|
||||
},
|
||||
panel: {
|
||||
lang: locale.value,
|
||||
'data-testid': props.panelTestId ?? `${props.testId}-panel`,
|
||||
},
|
||||
}))
|
||||
|
||||
watch(
|
||||
locale,
|
||||
(nextLocale) => {
|
||||
const supportedLocale = normalizeDatePickerLocale(nextLocale)
|
||||
primeVue.config.locale = {
|
||||
...(primeVue.config.locale ?? primeVueDatePickerLocales['en-US']),
|
||||
...primeVueDatePickerLocales[supportedLocale],
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.localized-date-picker {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.localized-date-picker :deep(.p-inputtext) {
|
||||
width: 100%;
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.localized-date-picker :deep(.p-datepicker-input-icon-container) {
|
||||
right: 12px;
|
||||
color: var(--th-color-navy-950);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.localized-date-picker-panel {
|
||||
z-index: 1200;
|
||||
color: var(--th-color-navy-950);
|
||||
font-family: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -31,15 +31,16 @@
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<input
|
||||
<LocalizedDatePicker
|
||||
v-else-if="isEditable(field) && isDateField(field)"
|
||||
class="v4-field__control"
|
||||
type="date"
|
||||
:model-value="dateFieldValue(field)"
|
||||
:input-id="dateFieldInputId(field)"
|
||||
:name="fieldKey(field)"
|
||||
:aria-invalid="fieldError(field) ? 'true' : 'false'"
|
||||
:value="fieldValue(field)"
|
||||
@input="updateField(field, $event)"
|
||||
>
|
||||
:test-id="fieldKey(field)"
|
||||
:placeholder="t('taskV4.field.datePlaceholder')"
|
||||
:invalid="Boolean(fieldError(field))"
|
||||
@update:model-value="updateFieldValue(field, $event)"
|
||||
/>
|
||||
|
||||
<input
|
||||
v-else-if="isEditable(field) && isCheckboxField(field)"
|
||||
@@ -120,6 +121,7 @@
|
||||
import { computed, reactive, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import LocalizedDatePicker from '@/components/common/LocalizedDatePicker.vue'
|
||||
import {
|
||||
fetchReservationV4AccountLookups,
|
||||
fetchReservationV4RateCodeLookups,
|
||||
@@ -225,6 +227,10 @@ function fieldKey(field: ReservationV4TaskCardFieldResult): string {
|
||||
return reservationV4FieldKey(field)
|
||||
}
|
||||
|
||||
function dateFieldInputId(field: ReservationV4TaskCardFieldResult): string {
|
||||
return `v4-date-${fieldKey(field).replace(/[^a-zA-Z0-9_-]/g, '-')}`
|
||||
}
|
||||
|
||||
function isEditable(field: ReservationV4TaskCardFieldResult): boolean {
|
||||
const key = reservationV4FieldKey(field)
|
||||
return !props.readOnly &&
|
||||
@@ -296,6 +302,11 @@ function fieldValue(field: ReservationV4TaskCardFieldResult): string | number {
|
||||
return stringifyV4Value(value)
|
||||
}
|
||||
|
||||
function dateFieldValue(field: ReservationV4TaskCardFieldResult): string {
|
||||
const value = readV4FieldValue(field, props.modelValue)
|
||||
return typeof value === 'string' ? value : stringifyV4Value(value)
|
||||
}
|
||||
|
||||
function staticFieldValue(field: ReservationV4TaskCardFieldResult): string {
|
||||
const value = fieldValue(field)
|
||||
const matchedOption = fieldOptions(field).find((option) => option.value === value)
|
||||
@@ -309,10 +320,14 @@ function checkboxValue(field: ReservationV4TaskCardFieldResult): boolean {
|
||||
|
||||
function updateField(field: ReservationV4TaskCardFieldResult, event: Event): void {
|
||||
const target = event.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
|
||||
updateFieldValue(field, target.value)
|
||||
}
|
||||
|
||||
function updateFieldValue(field: ReservationV4TaskCardFieldResult, value: string): void {
|
||||
delete invalidLookupValues[reservationV4FieldKey(field)]
|
||||
emit('update:modelValue', {
|
||||
...props.modelValue,
|
||||
[reservationV4FieldKey(field)]: target.value,
|
||||
[reservationV4FieldKey(field)]: value,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user