| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [x] TU/TI/TF rédigée - [x] TU/TI/TF OK - [x] CHANGELOG modifié --------- Co-authored-by: admin malio <malio@yuno.malio.fr> Co-authored-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr> Co-authored-by: matthieu <matthieu@yuno.malio.fr> Reviewed-on: #72 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #72.
This commit is contained in:
@@ -10,14 +10,17 @@
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:hint="hint"
|
||||
:error="error"
|
||||
:error="mergedError"
|
||||
:success="success"
|
||||
:clearable="clearable"
|
||||
:editable="editable"
|
||||
placeholder-template="JJ/MM/AAAA HH:MM"
|
||||
:input-class="inputClass"
|
||||
:label-class="labelClass"
|
||||
:group-class="groupClass"
|
||||
v-bind="$attrs"
|
||||
@clear="onClear"
|
||||
@commit="onCommit"
|
||||
>
|
||||
<template #default="{ currentMonth, currentYear }">
|
||||
<MonthGrid
|
||||
@@ -47,7 +50,8 @@ import CalendarField from './internal/CalendarField.vue'
|
||||
import MonthGrid from './internal/MonthGrid.vue'
|
||||
import MalioTimePicker from '../time/TimePicker.vue'
|
||||
import {formatTime} from '../time/composables/timeFormat'
|
||||
import {composeDateTime, formatIsoDateTimeToDisplay, isValidIsoDateTime, splitDateTime} from './composables/datetimeFormat'
|
||||
import {isDateInRange} from './composables/dateFormat'
|
||||
import {composeDateTime, formatIsoDateTimeToDisplay, isValidIsoDateTime, parseDisplayToIsoDateTime, splitDateTime} from './composables/datetimeFormat'
|
||||
|
||||
defineOptions({name: 'MalioDateTime', inheritAttrs: false})
|
||||
|
||||
@@ -67,6 +71,8 @@ const props = withDefaults(
|
||||
min?: string
|
||||
max?: string
|
||||
clearable?: boolean
|
||||
editable?: boolean
|
||||
invalidMessage?: string
|
||||
inputClass?: string
|
||||
labelClass?: string
|
||||
groupClass?: string
|
||||
@@ -86,13 +92,18 @@ const props = withDefaults(
|
||||
min: undefined,
|
||||
max: undefined,
|
||||
clearable: true,
|
||||
editable: false,
|
||||
invalidMessage: 'Date invalide',
|
||||
inputClass: '',
|
||||
labelClass: '',
|
||||
groupClass: '',
|
||||
},
|
||||
)
|
||||
|
||||
const emit = defineEmits<{(e: 'update:modelValue', value: string | null): void}>()
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string | null): void
|
||||
(e: 'update:valid', value: boolean): void
|
||||
}>()
|
||||
|
||||
// pendingTime : heure réglée avant qu'un jour ne soit choisi (sinon on ne peut pas émettre).
|
||||
const pendingTime = ref('')
|
||||
@@ -102,17 +113,29 @@ const datePart = computed(() => parts.value.date)
|
||||
const displayValue = computed(() => formatIsoDateTimeToDisplay(props.modelValue ?? null))
|
||||
const timeValue = computed(() => parts.value.time || pendingTime.value)
|
||||
|
||||
const internalError = ref('')
|
||||
const mergedError = computed(() => props.error || internalError.value)
|
||||
|
||||
// La validité ne reflète que la saisie clavier : malformée/hors plage → false. Un
|
||||
// champ vide est valide (l'obligation `required` reste à la charge du parent).
|
||||
const setError = (message: string) => {
|
||||
internalError.value = message
|
||||
emit('update:valid', message === '')
|
||||
}
|
||||
|
||||
function onSelectDay(iso: string) {
|
||||
// Si aucune heure n'a été choisie, on prend l'heure actuelle (pas 00:00).
|
||||
// (heure courante au moment du clic)
|
||||
const now = new Date()
|
||||
const time = parts.value.time || pendingTime.value || formatTime(now.getHours(), now.getMinutes())
|
||||
setError('')
|
||||
emit('update:modelValue', composeDateTime(iso, time))
|
||||
}
|
||||
|
||||
function onTimeChange(value: string | null) {
|
||||
if (!value) return
|
||||
if (datePart.value) {
|
||||
setError('')
|
||||
emit('update:modelValue', composeDateTime(datePart.value, value))
|
||||
}
|
||||
else {
|
||||
@@ -120,14 +143,34 @@ function onTimeChange(value: string | null) {
|
||||
}
|
||||
}
|
||||
|
||||
function onCommit(text: string) {
|
||||
const trimmed = text.trim()
|
||||
if (trimmed === '') {
|
||||
setError('')
|
||||
emit('update:modelValue', null)
|
||||
return
|
||||
}
|
||||
const iso = parseDisplayToIsoDateTime(trimmed)
|
||||
if (iso && isDateInRange(iso, props.min, props.max)) {
|
||||
setError('')
|
||||
emit('update:modelValue', iso)
|
||||
return
|
||||
}
|
||||
setError(props.invalidMessage)
|
||||
}
|
||||
|
||||
function onClear() {
|
||||
setError('')
|
||||
pendingTime.value = ''
|
||||
emit('update:modelValue', null)
|
||||
}
|
||||
|
||||
// immediate : émet aussi la validité au montage, pour que le parent connaisse
|
||||
// l'état d'un champ pré-rempli (formulaire d'édition) sans interaction préalable.
|
||||
watch(() => props.modelValue, (val) => {
|
||||
setError('')
|
||||
if (val && !isValidIsoDateTime(val) && import.meta.dev) {
|
||||
console.warn(`[MalioDateTime] modelValue invalide ignoré : "${val}"`)
|
||||
}
|
||||
})
|
||||
}, {immediate: true})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user