GeneIT/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx

177 lines
4.6 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 { ComplexFamilyTree } from "../../widgets/complex_family_tree/ComplexFamilyTree";
import { SimpleFamilyTree } from "../../widgets/simple_family_tree/SimpleFamilyTree";
enum CurrTab {
BasicTree,
SimpleTree,
AdvancedTree,
}
enum TreeMode {
Ascending,
Descending,
}
export function FamilyMemberTreeRoute(): React.ReactElement {
const { memberId } = useParams();
const family = useFamily();
const [currTab, setCurrTab] = React.useState(CurrTab.SimpleTree);
const [currMode, setCurrMode] = React.useState(TreeMode.Descending);
const member = family.members.get(Number(memberId));
const memo: [FamilyTreeNode, number] | null = React.useMemo(() => {
if (!member) return null;
const tree =
currMode === TreeMode.Ascending
? buildAscendingTree(member.id, family.members, family.couples)
: buildDescendingTree(member.id, family.members, family.couples);
return [tree, treeHeight(tree)];
}, [member, currMode, family.members, family.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("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" />
<Tab tabIndex={CurrTab.AdvancedTree} label="Avancé" />
</Tabs>
</div>
{/* the tree itself */}
<Paper style={{ flex: "1" }}>
{currTab === CurrTab.BasicTree ? (
<BasicFamilyTree tree={tree!} depth={currDepth} />
) : currTab === CurrTab.SimpleTree ? (
<SimpleFamilyTree
tree={tree!}
isUp={currMode === TreeMode.Ascending}
depth={currDepth}
/>
) : (
<ComplexFamilyTree
tree={tree!}
isUp={currMode === TreeMode.Ascending}
depth={currDepth}
/>
)}
</Paper>
</div>
);
}