Support for all event types (#212)

This commit is contained in:
czifumasa 2025-09-04 22:58:04 +02:00 committed by GitHub
parent 4d468b8d2e
commit 4d05cd9448
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 169 additions and 48 deletions

View File

@ -12,20 +12,14 @@ import {
mapToSource,
} from '../util/gedcom_util';
import {AdditionalFiles} from './additional-files';
import {Events} from './events';
import {ALL_SUPPORTED_EVENT_TYPES, Events} from './events';
import {MultilineText} from './multiline-text';
import {Sources} from './sources';
import {TranslatedTag} from './translated-tag';
import {WrappedImage} from './wrapped-image';
const EXCLUDED_TAGS = [
'BIRT',
'BAPM',
'CHR',
'EVEN',
'CENS',
'DEAT',
'BURI',
...ALL_SUPPORTED_EVENT_TYPES,
'NAME',
'SEX',
'FAMC',

View File

@ -18,6 +18,7 @@ import {
mapToSource,
pointerToId,
resolveDate,
resolveType,
Source,
} from '../util/gedcom_util';
import {FileEntry} from './additional-files';
@ -52,7 +53,8 @@ interface Props {
}
interface EventData {
type: string;
tag: string;
type?: string;
date?: DateOrRange;
age?: string;
personLink?: GedcomEntry;
@ -64,25 +66,73 @@ interface EventData {
indi: string;
}
const EVENT_TAGS = [
'BIRT',
const BIRTH_EVENT_TAGS = ['BIRT'];
const INDI_EVENT_TAGS = [
'ADOP',
'BAPM',
'CHR',
'FAMS',
'EVEN',
'BARM',
'BASM',
'BLES',
'CENS',
'DEAT',
'BURI',
'CHR',
'CHRA',
'CONF',
'EDUC',
'EMIG',
'EVEN',
'FAMS',
'FCOM',
'GRAD',
'IMMI',
'NATU',
'ORDN',
'OCCU',
'PROP',
'RESI',
'RETI',
'WILL',
'_DEG',
'_ELEC',
'_MDCL',
'_MILT',
];
const FAMILY_EVENT_TAGS = ['MARR', 'DIV'];
const FAMILY_EVENT_TAGS = [
'ANUL',
'CENS',
'DIV',
'DIVF',
'ENGA',
'EVEN',
'MARB',
'MARC',
'MARL',
'MARR',
'MARS',
];
const LIFE_EVENT_TAGS = [...INDI_EVENT_TAGS, ...FAMILY_EVENT_TAGS];
const DEATH_EVENT_TAGS = ['DEAT'];
const AFTER_DEATH_EVENT_TAGS = ['BURI', 'CREM', 'PROB'];
const SORTED_EVENT_TYPE_GROUPS = [
BIRTH_EVENT_TAGS,
LIFE_EVENT_TAGS,
DEATH_EVENT_TAGS,
AFTER_DEATH_EVENT_TAGS,
];
export const ALL_SUPPORTED_EVENT_TYPES = [
...BIRTH_EVENT_TAGS,
...LIFE_EVENT_TAGS,
...DEATH_EVENT_TAGS,
...AFTER_DEATH_EVENT_TAGS,
];
function EventHeader(props: {event: EventData}) {
const intl = useIntl();
return (
<div className="item-header">
<Header as="span" size="small">
<TranslatedTag tag={props.event.type} />
<TranslatedTag tag={getEventTitle(props.event)} />
</Header>
{props.event.date ? (
<Header as="span" textAlign="right" sub>
@ -93,6 +143,13 @@ function EventHeader(props: {event: EventData}) {
);
}
function getEventTitle(event: EventData) {
if (event.tag === 'EVEN' && event.type) {
return event.type;
}
return event.tag;
}
function getSpouse(indi: string, familyEntry: GedcomEntry, gedcom: GedcomData) {
const spouseReference = familyEntry.tree
.filter((familySubEntry) => ['WIFE', 'HUSB'].includes(familySubEntry.tag))
@ -110,13 +167,13 @@ function getAge(
gedcom: GedcomData,
intl: IntlShape,
): string | undefined {
if (eventEntry.tag !== 'DEAT') {
if (!DEATH_EVENT_TAGS.includes(eventEntry.tag)) {
return undefined;
}
const deathDate = resolveDate(eventEntry);
const birthDate = gedcom.indis[indi].tree
.filter((indiSubEntry) => indiSubEntry.tag === 'BIRT')
.filter((indiSubEntry) => BIRTH_EVENT_TAGS.includes(indiSubEntry.tag))
.map((birthEvent) => resolveDate(birthEvent))
.find((topolaDate) => topolaDate);
@ -176,10 +233,25 @@ function eventSources(entry: GedcomEntry, gedcom: GedcomData): Source[] {
}
function eventNotes(entry: GedcomEntry, gedcom: GedcomData): string[][] {
return entry.tree
.filter((subentry) => ['NOTE', 'TYPE'].includes(subentry.tag))
.map((note) => dereference(note, gedcom, (gedcom) => gedcom.other))
.map((note) => getData(note));
const externalNotes = entry.tree
.filter((subEntry) => subEntry.tag === 'NOTE')
.map((note) => dereference(note, gedcom, (gedcom) => gedcom.other));
//for generic 'EVEN' tag 'TYPE is mandatory and is part of the header, for other types it can be worth it to display it as a note
const type =
entry.tag !== 'EVEN'
? entry.tree.filter((subEntry) => subEntry.tag === 'TYPE')
: [];
//entry.data contains event description, so it's also displayed in notes section
return (
[entry, ...type, ...externalNotes]
.filter((entry) => !!entry.data)
/* In Gedcom 'Y' only indicates event occurred, but it doesn't contain any valuable information
like place, date or description, so it should be omitted when fetching entry data. */
.filter((entry) => entry.data !== 'Y')
.map((note) => getData(note))
);
}
function toEvent(
@ -203,8 +275,9 @@ function toIndiEvent(
const date = resolveDate(entry) || null;
return [
{
tag: entry.tag,
date: date ? getDate(date.data) : undefined,
type: entry.tag,
type: resolveType(entry),
age: getAge(entry, indi, gedcom, intl),
place: eventPlace(entry),
images: eventImages(entry, gedcom),
@ -224,17 +297,18 @@ function toFamilyEvents(
const family = dereference(entry, gedcom, (gedcom) => gedcom.fams);
return flatMap(FAMILY_EVENT_TAGS, (tag) =>
family.tree.filter((entry) => entry.tag === tag),
).map((familyMarriageEvent) => {
const date = resolveDate(familyMarriageEvent) || null;
).map((familyEvent) => {
const date = resolveDate(familyEvent) || null;
return {
tag: familyEvent.tag,
date: date ? getDate(date.data) : undefined,
type: familyMarriageEvent.tag,
type: resolveType(familyEvent),
personLink: getSpouse(indi, family, gedcom),
place: eventPlace(familyMarriageEvent),
images: eventImages(familyMarriageEvent, gedcom),
files: eventFiles(familyMarriageEvent, gedcom),
notes: eventNotes(familyMarriageEvent, gedcom),
sources: eventSources(familyMarriageEvent, gedcom),
place: eventPlace(familyEvent),
images: eventImages(familyEvent, gedcom),
files: eventFiles(familyEvent, gedcom),
notes: eventNotes(familyEvent, gedcom),
sources: eventSources(familyEvent, gedcom),
indi: indi,
};
});
@ -267,9 +341,9 @@ function Event(props: {event: EventData}) {
export function Events(props: Props) {
const intl = useIntl();
const events = flatMap(EVENT_TAGS, (tag) =>
const events = flatMap(SORTED_EVENT_TYPE_GROUPS, (eventTypeGroup) =>
props.entries
.filter((entry) => entry.tag === tag)
.filter((entry) => eventTypeGroup.includes(entry.tag))
.map((eventEntry) => toEvent(eventEntry, props.gedcom, props.indi, intl))
.flatMap((events) => events)
.sort((event1, event2) => compareDates(event1.date, event2.date)),

View File

@ -3,27 +3,49 @@ import {FormattedMessage} from 'react-intl';
const TAG_DESCRIPTIONS = new Map([
['ADOP', 'Adoption'],
['BAPM', 'Baptism'],
['BARM', 'Bar Mitzvah'],
['BASM', 'Bas Mitzvah'],
['BIRT', 'Birth'],
['BLES', 'Blessing'],
['BURI', 'Burial'],
['CENS', 'Census'],
['CHR', 'Christening'],
['CHRA', 'Adult christening'],
['CONF', 'Confirmation'],
['CREM', 'Cremation'],
['DEAT', 'Death'],
['DEG', 'Degree'],
['DIV', 'Divorce'],
['DIVF', 'Divorce filed'],
['EDUC', 'Education'],
['ELEC', 'Elected'],
['EMAIL', 'E-mail'],
['EMIG', 'Emigration'],
['ENGA', 'Engagement'],
['EVEN', 'Event'],
['FACT', 'Fact'],
['FCOM', 'First communion'],
['GRAD', 'Graduation'],
['IMMI', 'Immigration'],
['MARB', 'Marriage bann'],
['MARC', 'Marriage contract'],
['MARL', 'Marriage license'],
['MARR', 'Marriage'],
['DIV', 'Divorce'],
['MARS', 'Marriage settlement'],
['MDCL', 'Medical info'],
['MILT', 'Military services'],
['NATU', 'Naturalization'],
['OCCU', 'Occupation'],
['TITL', 'Title'],
['WWW', 'WWW'],
['OBJE', 'Additional files'],
['OCCU', 'Occupation'],
['ORDN', 'Ordination'],
['PROB', 'Probate'],
['PROP', 'Property'],
['RESI', 'Residence'],
['RETI', 'Retirement'],
['SOUR', 'Sources'],
['TITL', 'Title'],
['WILL', 'Will'],
['WWW', 'WWW'],
['birth', 'Birth name'],
['married', 'Married name'],
['maiden', 'Maiden name'],

View File

@ -39,27 +39,54 @@
"select_wikitree_id.comment": "Wpisz identyfikator profilu {wikiTreeLink}. Przykłady: {example1}, {example2}",
"select_wikitree_id.cancel": "Anuluj",
"select_wikitree_id.load": "Otwórz",
"gedcom.ADOP": "Adopcja",
"gedcom.BAPM": "Chrzest",
"gedcom.BARM": "Bar Micwa",
"gedcom.BASM": "Bat Micwa",
"gedcom.BIRT": "Narodziny",
"gedcom.BLES": "Błogosławieństwo",
"gedcom.BURI": "Pogrzeb",
"gedcom.CENS": "Spis ludności",
"gedcom.CHR": "Chrzest",
"gedcom.CHRA": "Chrzest dorosłych",
"gedcom.CONF": "Bierzmowanie",
"gedcom.CREM": "Kremacja",
"gedcom.DEAT": "Śmierć",
"gedcom.DEG": "Stopień naukowy",
"gedcom.DIV": "Rozwód",
"gedcom.DIVF": "Wniesienie pozwu o rozwód",
"gedcom.DSCR": "Opis",
"gedcom.EDUC": "Wykształcenie",
"gedcom.ELEC": "Wybór na stanowisko",
"gedcom.EMAIL": "E-mail",
"gedcom.EMIG": "Emigracja",
"gedcom.ENGA": "Zaręczyny",
"gedcom.EVEN": "Wydarzenie",
"gedcom.FACT": "Fakt",
"gedcom.MILT": "Służba wojskowa",
"gedcom.OCCU": "Zawód",
"gedcom.RIN": "ID",
"gedcom.TITL": "Tytuł",
"gedcom.WWW": "Strona WWW",
"gedcom.OBJE": "Dodatkowe pliki",
"gedcom.SOUR": "Źródła",
"gedcom._UPD": "Ostatnia aktualizacja",
"gedcom.FCOM": "Pierwsza komunia",
"gedcom.GRAD": "Ukończenie szkoły",
"gedcom.IMMI": "Imigracja",
"gedcom.MARB": "Zapowiedzi małżeńskie",
"gedcom.MARC": "Kontrakt małżeński",
"gedcom.MARL": "Licencja małżeńska",
"gedcom.MARR": "Małżeństwo",
"gedcom.DIV": "Rozwód",
"gedcom.MARS": "Ugoda małżeńska",
"gedcom.MDCL": "Informacje medyczne",
"gedcom.MILT": "Służba wojskowa",
"gedcom.NATU": "Nadanie obywatelstwa",
"gedcom.OBJE": "Dodatkowe pliki",
"gedcom.OCCU": "Zawód",
"gedcom.ORDN": "Święcenia",
"gedcom.PROB": "Postępowanie spadkowe",
"gedcom.PROP": "Nieruchomość",
"gedcom.RESI": "Miejsce zamieszkania",
"gedcom.RETI": "Emerytura",
"gedcom.RIN": "ID",
"gedcom.SOUR": "Źródła",
"gedcom.TITL": "Tytuł",
"gedcom.WILL": "Testament",
"gedcom.WWW": "Strona WWW",
"gedcom._UPD": "Ostatnia aktualizacja",
"gedcom.birth": "Nazwisko rodowe",
"gedcom.married": "Nazwisko po małżeństwie",
"gedcom.maiden": "Nazwisko panieńskie",

View File

@ -332,6 +332,10 @@ export function resolveDate(entry: GedcomEntry) {
return entry.tree.find((subEntry) => subEntry.tag === 'DATE');
}
export function resolveType(entry: GedcomEntry) {
return entry.tree.find((subEntry) => subEntry.tag === 'TYPE')?.data;
}
export function mapToSource(
sourceEntryReference: GedcomEntry,
gedcom: GedcomData,