Files
GeneIT/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx
Pierre Hubert c8ee881b2c
All checks were successful
continuous-integration/drone/push Build is passing
Genealogy as a feature (#175)
Start our journey into turning GeneIT as afully featured family intranet by making genealogy a feature that can be disabled by family admins

Reviewed-on: #175
2024-05-16 19:15:15 +00:00

166 lines
4.3 KiB
TypeScript

import ClearIcon from "@mui/icons-material/Clear";
import {
Alert,
FormControl,
FormControlLabel,
FormLabel,
IconButton,
InputLabel,
MenuItem,
Paper,
Radio,
RadioGroup,
Select,
Tab,
Tabs,
} from "@mui/material";
import React from "react";
import { useParams } from "react-router-dom";
import {
FamilyTreeNode,
buildAscendingTree,
buildDescendingTree,
treeHeight,
} from "../../../utils/family_tree";
import { useFamily } from "../../../widgets/BaseFamilyRoute";
import { BasicFamilyTree } from "../../../widgets/BasicFamilyTree";
import { MemberItem } from "../../../widgets/MemberItem";
import { RouterLink } from "../../../widgets/RouterLink";
import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute";
import { SimpleFamilyTree } from "../../../widgets/simple_family_tree/SimpleFamilyTree";
enum CurrTab {
BasicTree,
SimpleTree,
}
enum TreeMode {
Ascending,
Descending,
}
export function FamilyMemberTreeRoute(): React.ReactElement {
const { memberId } = useParams();
const genealogy = useGenealogy();
const family = useFamily();
const [currTab, setCurrTab] = React.useState(CurrTab.SimpleTree);
const [currMode, setCurrMode] = React.useState(TreeMode.Descending);
const member = genealogy.members.get(Number(memberId));
const memo: [FamilyTreeNode, number] | null = React.useMemo(() => {
if (!member) return null;
const tree =
currMode === TreeMode.Ascending
? buildAscendingTree(member.id, genealogy.members, genealogy.couples)
: buildDescendingTree(member.id, genealogy.members, genealogy.couples);
return [tree, treeHeight(tree)];
}, [member, currMode, genealogy.members, genealogy.couples]);
const [currDepth, setCurrDepth] = React.useState(0);
if (!member) {
return (
<Alert severity="error">
L'arbre ne peut pas être constuit : le membre n'existe pas !
</Alert>
);
}
const [tree, maxDepth] = memo!;
if (currDepth === 0) setCurrDepth(maxDepth);
return (
<div
style={{
flex: "1",
display: "flex",
flexDirection: "column",
marginBottom: "10px",
}}
>
{/* parent bar */}
<div style={{ display: "flex" }}>
<MemberItem
dense
member={member}
secondary={
<RouterLink to={family.family.URL("genealogy/tree")}>
<IconButton>
<ClearIcon />
</IconButton>
</RouterLink>
}
/>
<div style={{ flex: "10" }}></div>
<FormControl>
<FormLabel>Arbre</FormLabel>
<RadioGroup
row
value={currMode}
onChange={(_e, v) => {
setCurrDepth(0);
setCurrMode(Number(v));
}}
>
<FormControlLabel
value={TreeMode.Descending}
control={<Radio />}
label="Descendant"
/>
<FormControlLabel
value={TreeMode.Ascending}
control={<Radio />}
label="Ascendant"
/>
</RadioGroup>
</FormControl>
<div style={{ flex: "1" }}></div>
<FormControl variant="standard" sx={{ m: 1, minWidth: 120 }}>
<InputLabel>Profondeur</InputLabel>
<Select
value={currDepth}
onChange={(v) => setCurrDepth(Number(v.target.value))}
label="Profondeur"
>
{Array(maxDepth)
.fill(0)
.map((_v, index) => (
<MenuItem key={index} value={index + 1}>
{index + 1}
</MenuItem>
))}
</Select>
</FormControl>
<div style={{ flex: "1" }}></div>
<Tabs
value={currTab}
onChange={(_e, v) => setCurrTab(v)}
aria-label="basic tabs example"
>
<Tab tabIndex={CurrTab.BasicTree} label="Basique" />
<Tab tabIndex={CurrTab.SimpleTree} label="Simple" />
</Tabs>
</div>
{/* the tree itself */}
<Paper style={{ flex: "1", display: "flex", flexDirection: "column" }}>
{currTab === CurrTab.BasicTree ? (
<BasicFamilyTree tree={tree!} depth={currDepth} />
) : (
<SimpleFamilyTree tree={tree!} depth={currDepth} />
)}
</Paper>
</div>
);
}