Build tree couples

This commit is contained in:
Pierre HUBERT 2023-08-21 17:53:51 +02:00
parent c414defb19
commit 4d5bdaad57
4 changed files with 108 additions and 6 deletions

View File

@ -1,5 +1,6 @@
import { APIClient } from "./ApiClient"; import { APIClient } from "./ApiClient";
import { DateValue, Member } from "./MemberApi"; import { DateValue, Member } from "./MemberApi";
import { ServerApi } from "./ServerApi";
interface CoupleApiInterface { interface CoupleApiInterface {
id: number; id: number;
@ -99,6 +100,10 @@ export class Couple implements CoupleApiInterface {
day: this.divorce_day, day: this.divorce_day,
}; };
} }
otherPersonID(id: number): number | undefined {
return id === this.wife ? this.husband : this.wife;
}
} }
export class CouplesList { export class CouplesList {
@ -137,6 +142,10 @@ export class CouplesList {
getAllOf(m: Member): Couple[] { getAllOf(m: Member): Couple[] {
return this.filter((c) => c.husband === m.id || c.wife === m.id); return this.filter((c) => c.husband === m.id || c.wife === m.id);
} }
getFirstMariedOf(m: Member): Couple | undefined {
return this.getAllOf(m).find((c) => (c.state = "M"));
}
} }
export class CoupleApi { export class CoupleApi {

View File

@ -1,5 +1,4 @@
import { useParams } from "react-router-dom"; import ClearIcon from "@mui/icons-material/Clear";
import { useFamily } from "../../widgets/BaseFamilyRoute";
import { import {
Alert, Alert,
FormControl, FormControl,
@ -12,10 +11,15 @@ import {
Tab, Tab,
Tabs, Tabs,
} from "@mui/material"; } from "@mui/material";
import { MemberItem } from "../../widgets/MemberItem";
import ClearIcon from "@mui/icons-material/Clear";
import { RouterLink } from "../../widgets/RouterLink";
import React from "react"; import React from "react";
import { useParams } from "react-router-dom";
import {
buildAscendingTree,
buildDescendingTree,
} from "../../utils/family_tree";
import { useFamily } from "../../widgets/BaseFamilyRoute";
import { MemberItem } from "../../widgets/MemberItem";
import { RouterLink } from "../../widgets/RouterLink";
enum CurrTab { enum CurrTab {
BasicTree, BasicTree,
@ -37,6 +41,16 @@ export function FamilyMemberTreeRoute(): React.ReactElement {
const member = family.members.get(Number(memberId)); const member = family.members.get(Number(memberId));
const tree = React.useMemo(
() =>
!member
? null
: currMode === TreeMode.Ascending
? buildAscendingTree(member.id, family.members, family.couples)
: buildDescendingTree(member.id, family.members, family.couples),
[member, currMode, family.members, family.couples]
);
if (!member) { if (!member) {
return ( return (
<Alert severity="error"> <Alert severity="error">

View File

@ -1,6 +1,6 @@
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { MemberInput } from "../../widgets/forms/MemberInput";
import { useFamily } from "../../widgets/BaseFamilyRoute"; import { useFamily } from "../../widgets/BaseFamilyRoute";
import { MemberInput } from "../../widgets/forms/MemberInput";
export function FamilyTreeRoute(): React.ReactElement { export function FamilyTreeRoute(): React.ReactElement {
const n = useNavigate(); const n = useNavigate();

View File

@ -0,0 +1,79 @@
import { Couple, CouplesList } from "../api/CoupleApi";
import { Member, MembersList } from "../api/MemberApi";
export interface CoupleInformation {
couple: Couple;
member: Member;
down: FamilyTreeNode[];
}
export interface FamilyTreeNode {
down?: FamilyTreeNode[];
member: Member;
couples?: CoupleInformation[];
}
export function buildAscendingTree(
memberId: number,
members: MembersList,
couples: CouplesList
): FamilyTreeNode {
const member = members.get(memberId)!;
const parents = [];
if (member.father)
parents.push(buildAscendingTree(member.father, members, couples));
if (member.mother)
parents.push(buildAscendingTree(member.mother, members, couples));
return {
member: member,
down: parents,
};
}
export function buildDescendingTree(
memberId: number,
members: MembersList,
couples: CouplesList
): FamilyTreeNode {
const member = members.get(memberId)!;
const children = members.children(member.id);
// Process user couples
const member_couples: CoupleInformation[] = [];
for (const c of couples.getAllOf(member)) {
// Currently, couples with missing pair information are not supported
const pairId = c.otherPersonID(member.id);
if (!pairId) continue;
const pair = members.get(pairId);
const c_children: Member[] = [];
// Determine children associated with each couple
for (let index = 0; index < children.length; ) {
const c = children[index];
if (c.mother !== pairId && c.father !== pairId) {
index++;
continue;
}
children.splice(index, 1);
c_children.push(c);
}
member_couples.push({
couple: c,
member: pair!,
down: c_children.map((c) => buildDescendingTree(c.id, members, couples)),
});
}
return {
member: member,
down: children.map((c) => buildDescendingTree(c.id, members, couples)),
couples: member_couples,
};
}