mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-14 08:30:50 +00:00
fix(vie): une union sans date a sa place logique, plus apres le deces du conjoint
Un mariage sans date tombait tout en bas de l'onglet Vie, apres le deces du conjoint, ce qui ne voulait rien dire. Il se place maintenant juste avant le premier enfant du couple, sinon avant la fin de l'union ou le deces du conjoint. Aucune annee n'est inventee : colonne vide et « date inconnue ». Seul ce qui n'a aucun repere reste en bas, et tout moment sans date le dit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e98125b796
commit
68ac2fa8f8
3 files changed
+41
-7
No files matched your search
@@ -436,6 +436,8 @@ const PersonCard = ({
|
||||
unions: personUnions.map((union) => ({
|
||||
...union,
|
||||
partner: persons.find((p) => p.id === (union.partner1Id === person.id ? union.partner2Id : union.partner1Id)) || null,
|
||||
// Enfants du couple : placent dans la frise une union dont la date manque
|
||||
childIds: filiations.filter((f) => f.unionId && String(f.unionId) === String(union.id)).map((f) => f.childId),
|
||||
})),
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ const siblingWord = (p) => {
|
||||
|
||||
/**
|
||||
* @param person personne de la fiche (birthDate, deathDate, birthPlace, birthYear, deathYear)
|
||||
* @param family { parents, children, siblings, unions: [{ id, partner, startYear, endYear, unionType }] }
|
||||
* @param family { parents, children, siblings, unions: [{ id, partner, startYear, endYear, unionType, childIds }] }
|
||||
* @param life réponse de GET /trees/:id/persons/:personId/life, ou null tant qu'elle n'est pas là
|
||||
* @returns entrées triées { key, year, kind: 'mile' | 'minor' | 'fam', title, meta, note, sources, mediaIds,
|
||||
* event (moment modifiable), milestone ({ type, unionId } d'une naissance, d'un mariage, d'un décès) }
|
||||
@@ -144,10 +144,18 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
const partnerName = union.partner ? fullName(union.partner) : t('Conjoint inconnu')
|
||||
const place = formatPlace(detail.startPlace || '')
|
||||
const extra = sourcesOf('marriage', union.id)
|
||||
// Union sans date : à sa place logique, juste avant le premier enfant du couple, sinon avant la fin de
|
||||
// l'union ou le décès du conjoint. Aucune année n'est inventée, la colonne reste vide.
|
||||
const childIds = new Set((union.childIds || []).map(String))
|
||||
const childYears = (family.children || []).filter((c) => childIds.has(String(c.id))).map((c) => yearOf(c.birthDate) ?? c.birthYear).filter(within)
|
||||
const partnerDeath = union.partner ? yearOf(union.partner.deathDate) ?? union.partner.deathYear : null
|
||||
const anchor = year ? null : (childYears.length ? Math.min(...childYears) : null) ?? union.endYear ?? (within(partnerDeath) ? partnerDeath : null)
|
||||
out.push({
|
||||
key: `union-${union.id}`, year, order: 2, kind: 'mile',
|
||||
key: `union-${union.id}`, year, sortYear: anchor, order: year ? 2 : 1, kind: 'mile',
|
||||
title: union.unionType === 'union' ? t('Union avec {name}', { name: partnerName }) : t('Épouse {name}', { name: partnerName }),
|
||||
meta: joinMeta(place, detail.startDatePrecision ? describeDate(detail.startDate, null, detail.startDatePrecision) : '', ageAt(birthYear, year)),
|
||||
meta: year
|
||||
? joinMeta(place, detail.startDatePrecision ? describeDate(detail.startDate, null, detail.startDatePrecision) : '', ageAt(birthYear, year))
|
||||
: joinMeta(place, t('date inconnue')),
|
||||
note: extra?.notes || '', sources: extra?.sources || '',
|
||||
...milestoneFields(extra, { type: 'marriage', unionId: union.id }),
|
||||
})
|
||||
@@ -171,7 +179,7 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
}
|
||||
out.push({
|
||||
key: `event-${event.id}`, year, order: 1, kind: 'minor', title,
|
||||
meta: joinMeta(formatPlace(event.place || ''), describeDate(event.date, event.dateEnd, event.datePrecision), ageAt(birthYear, year)),
|
||||
meta: joinMeta(formatPlace(event.place || ''), year ? describeDate(event.date, event.dateEnd, event.datePrecision) : t('date inconnue'), ageAt(birthYear, year)),
|
||||
note: event.notes || '', sources: event.sources || '',
|
||||
mediaIds: event.mediaIds || [],
|
||||
// Seuls les moments propres à la personne se modifient depuis l'onglet (pas ceux d'une union)
|
||||
@@ -206,9 +214,9 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
})
|
||||
}
|
||||
|
||||
// Les entrées sans date restent en bas, dans l'ordre où elles sont arrivées
|
||||
// Une union sans date se range à sa place logique (sortYear) ; le reste sans date va en bas, dans l'ordre d'arrivée
|
||||
return out
|
||||
.map((entry, index) => ({ ...entry, index }))
|
||||
.sort((a, b) => (a.year ?? Infinity) - (b.year ?? Infinity) || a.order - b.order || a.index - b.index)
|
||||
.map(({ order, index, ...entry }) => entry) // eslint-disable-line no-unused-vars
|
||||
.sort((a, b) => (a.year ?? a.sortYear ?? Infinity) - (b.year ?? b.sortYear ?? Infinity) || a.order - b.order || a.index - b.index)
|
||||
.map(({ order, index, sortYear, ...entry }) => entry) // eslint-disable-line no-unused-vars
|
||||
}
|
||||
@@ -66,6 +66,30 @@ describe('frise de vie', () => {
|
||||
expect(entries.map((e) => [e.title, e.year, e.meta])).toEqual([['Naissance', 1900, ''], ['Décès', null, 'date inconnue']])
|
||||
})
|
||||
|
||||
it('union sans date : avant le premier enfant du couple, sinon avant le décès du conjoint, sinon en bas', () => {
|
||||
const lucie = { id: 1, firstName: 'Lucie', birthYear: 1940 }
|
||||
const entries = buildLifeTimeline(lucie, {
|
||||
children: [{ id: 7, firstName: 'Hugo', birthYear: 1966 }, { id: 8, firstName: 'Léa', birthYear: 1981 }],
|
||||
unions: [
|
||||
{ id: 'u1', partner: { id: 2, firstName: 'Marc', lastName: 'Roy', deathYear: 2013 }, unionType: 'mariage', childIds: [7] },
|
||||
{ id: 'u2', partner: { id: 3, firstName: 'Paul', lastName: 'Vidal', deathYear: 2016 }, unionType: 'mariage', childIds: [] },
|
||||
{ id: 'u3', partner: { id: 4, firstName: 'Yves', lastName: 'Mallet' }, unionType: 'mariage' },
|
||||
],
|
||||
}, null)
|
||||
expect(entries.map((e) => e.title)).toEqual([
|
||||
'Naissance', 'Épouse Marc Roy', 'Naissance de Hugo', 'Naissance de Léa', 'Décès de Marc', 'Épouse Paul Vidal', 'Décès de Paul', 'Épouse Yves Mallet',
|
||||
])
|
||||
// Aucune année inventée : colonne vide, « date inconnue » dit pourquoi
|
||||
for (const key of ['union-u1', 'union-u2', 'union-u3']) {
|
||||
expect(entries.find((e) => e.key === key)).toMatchObject({ year: undefined, meta: 'date inconnue' })
|
||||
}
|
||||
expect(entries.find((e) => e.key === 'union-u1')).not.toHaveProperty('sortYear')
|
||||
})
|
||||
|
||||
it('un moment sans date dit « date inconnue »', () => {
|
||||
expect(entries.find((e) => e.title === 'Résidence').meta).toBe('Rue des Écoles · date inconnue')
|
||||
})
|
||||
|
||||
it('dit les dates comme on les dit', () => {
|
||||
expect(describeDate('1879-01-01', null, 'about')).toBe('vers 1879')
|
||||
expect(describeDate('1879-01-01', null, 'before')).toBe('avant 1879')
|
||||
|
||||
Reference in new issue
Block a user