| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] 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: #77 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #77.
This commit is contained in:
@@ -180,6 +180,9 @@ const props = withDefaults(
|
||||
const emit = defineEmits<{
|
||||
(e: 'clear' | 'close'): void
|
||||
(e: 'commit', value: string): void
|
||||
// Mois affiché (month 0-11) : émis à l'ouverture du popover et à chaque
|
||||
// navigation, pour qu'un consommateur (ex. SIRH) charge les données du mois.
|
||||
(e: 'month-change', value: {month: number, year: number}): void
|
||||
}>()
|
||||
|
||||
const attrs = useAttrs()
|
||||
@@ -229,6 +232,12 @@ watch(isOpen, (value) => {
|
||||
if (!value) emit('close')
|
||||
})
|
||||
|
||||
// Émet le mois affiché tant que le popover est ouvert : une fois à l'ouverture
|
||||
// (isOpen → true, après syncToIso), puis à chaque changement de mois/année.
|
||||
watch([isOpen, currentMonth, currentYear], () => {
|
||||
if (isOpen.value) emit('month-change', {month: currentMonth.value, year: currentYear.value})
|
||||
})
|
||||
|
||||
const onFieldClick = () => {
|
||||
if (props.disabled || props.readonly) return
|
||||
if (props.editable) {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
|
||||
import {mount} from '@vue/test-utils'
|
||||
import type {DefineComponent} from 'vue'
|
||||
import MonthGrid from './MonthGrid.vue'
|
||||
|
||||
type MonthGridProps = {
|
||||
month: number
|
||||
year: number
|
||||
selectedDate?: string | null
|
||||
markedDates?: Record<string, 'success' | 'danger'>
|
||||
min?: string
|
||||
max?: string
|
||||
}
|
||||
|
||||
const Grid = MonthGrid as DefineComponent<MonthGridProps>
|
||||
const mountGrid = (props: MonthGridProps) => mount(Grid, {props, attachTo: document.body})
|
||||
|
||||
// Récupère la pastille (span rond) qui porte les classes de `cellClass` pour un jour donné.
|
||||
const pill = (wrapper: ReturnType<typeof mountGrid>, iso: string) =>
|
||||
wrapper.get(`[data-iso="${iso}"]`).get('span.rounded-full')
|
||||
|
||||
describe('MalioDateMonthGrid — markedDates', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
vi.setSystemTime(new Date(2026, 4, 19)) // 19 mai 2026
|
||||
})
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('applique un fond success sur un jour marqué', () => {
|
||||
const wrapper = mountGrid({month: 4, year: 2026, markedDates: {'2026-05-20': 'success'}})
|
||||
expect(pill(wrapper, '2026-05-20').classes()).toContain('bg-m-success/15')
|
||||
})
|
||||
|
||||
it('applique un fond danger sur un jour marqué', () => {
|
||||
const wrapper = mountGrid({month: 4, year: 2026, markedDates: {'2026-05-21': 'danger'}})
|
||||
expect(pill(wrapper, '2026-05-21').classes()).toContain('bg-m-danger/15')
|
||||
})
|
||||
|
||||
it('ne marque pas les jours absents de markedDates', () => {
|
||||
const wrapper = mountGrid({month: 4, year: 2026, markedDates: {'2026-05-20': 'success'}})
|
||||
const classes = pill(wrapper, '2026-05-22').classes()
|
||||
expect(classes).not.toContain('bg-m-success/15')
|
||||
expect(classes).not.toContain('bg-m-danger/15')
|
||||
})
|
||||
|
||||
it('précédence : la sélection (primary) prime sur la variante marquée', () => {
|
||||
const wrapper = mountGrid({
|
||||
month: 4,
|
||||
year: 2026,
|
||||
selectedDate: '2026-05-22',
|
||||
markedDates: {'2026-05-22': 'success'},
|
||||
})
|
||||
const classes = pill(wrapper, '2026-05-22').classes()
|
||||
expect(classes).toContain('bg-m-primary')
|
||||
expect(classes).toContain('text-white')
|
||||
expect(classes).not.toContain('bg-m-success/15')
|
||||
})
|
||||
|
||||
it('today marqué : garde sa bordure ET reçoit le fond marqué', () => {
|
||||
const wrapper = mountGrid({month: 4, year: 2026, markedDates: {'2026-05-19': 'success'}})
|
||||
const classes = pill(wrapper, '2026-05-19').classes()
|
||||
expect(classes).toContain('border-m-primary')
|
||||
expect(classes).toContain('bg-m-success/15')
|
||||
})
|
||||
|
||||
it('today non marqué : bordure sans fond marqué', () => {
|
||||
const wrapper = mountGrid({month: 4, year: 2026, markedDates: {'2026-05-20': 'success'}})
|
||||
const classes = pill(wrapper, '2026-05-19').classes()
|
||||
expect(classes).toContain('border-m-primary')
|
||||
expect(classes).not.toContain('bg-m-success/15')
|
||||
})
|
||||
})
|
||||
@@ -84,6 +84,14 @@ import {dayRangeRole, resolveRangeBounds, type DayRangeRole} from '../composable
|
||||
|
||||
defineOptions({name: 'MalioDateMonthGrid'})
|
||||
|
||||
// Statut générique par jour : aucune sémantique métier dans le layer, juste un
|
||||
// fond tokenisé. `success` et `danger` suffisent pour l'instant (MUI-45).
|
||||
type MarkedVariant = 'success' | 'danger'
|
||||
const markedBg: Record<MarkedVariant, string> = {
|
||||
success: 'bg-m-success/15',
|
||||
danger: 'bg-m-danger/15',
|
||||
}
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
month: number
|
||||
@@ -94,6 +102,7 @@ const props = withDefaults(
|
||||
previewDate?: string | null
|
||||
interactiveWeekNumber?: boolean
|
||||
markedWeekStart?: string | null
|
||||
markedDates?: Record<string, MarkedVariant>
|
||||
min?: string
|
||||
max?: string
|
||||
}>(),
|
||||
@@ -104,6 +113,7 @@ const props = withDefaults(
|
||||
previewDate: undefined,
|
||||
interactiveWeekNumber: false,
|
||||
markedWeekStart: null,
|
||||
markedDates: undefined,
|
||||
min: undefined,
|
||||
max: undefined,
|
||||
},
|
||||
@@ -165,6 +175,10 @@ const cellClass = (cell: DayCell) => {
|
||||
if (role === 'start' || role === 'end' || role === 'single') return 'bg-m-primary text-white'
|
||||
if (role === 'in-range') return 'text-black'
|
||||
const parts = ['hover:bg-m-primary/10']
|
||||
// Précédence : sélection/range (primary, return ci-dessus) > variante marquée > défaut.
|
||||
// `today` n'est pas exclusif : il garde sa bordure ET peut recevoir le fond marqué.
|
||||
const marked = props.markedDates?.[cell.isoDate]
|
||||
if (marked) parts.push(markedBg[marked])
|
||||
if (cell.isToday) parts.push('border border-m-primary text-m-primary')
|
||||
else if (cell.isCurrentMonth) parts.push('text-black')
|
||||
else parts.push('opacity-[60%]')
|
||||
|
||||
Reference in New Issue
Block a user