From 8cfe51fb0d0995b582be174f8e37e21bda7f4fb0 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Tue, 22 Aug 2023 11:31:04 +0200 Subject: [PATCH] Start to build basic family tree --- geneit_app/package-lock.json | 146 +++++++++++++----- geneit_app/package.json | 3 +- geneit_app/src/api/CoupleApi.ts | 1 - .../routes/family/FamilyMemberTreeRoute.tsx | 9 +- geneit_app/src/widgets/BasicFamilyTree.tsx | 81 ++++++++++ 5 files changed, 201 insertions(+), 39 deletions(-) create mode 100644 geneit_app/src/widgets/BasicFamilyTree.tsx diff --git a/geneit_app/package-lock.json b/geneit_app/package-lock.json index f6d7325..76ee6ad 100644 --- a/geneit_app/package-lock.json +++ b/geneit_app/package-lock.json @@ -15,7 +15,8 @@ "@mdi/js": "^7.2.96", "@mdi/react": "^1.6.1", "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.4", + "@mui/lab": "^5.0.0-alpha.140", + "@mui/material": "^5.14.5", "@mui/x-data-grid": "^6.9.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", @@ -3030,16 +3031,16 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-beta.6", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.6.tgz", - "integrity": "sha512-jcHy6HwOX7KzRhRtL8nvIvUlxvLx2Fl6NMRCyUSQSvMTyfou9kndekz0H4HJaXvG1Y4WEifk23RYedOlrD1kEQ==", + "version": "5.0.0-beta.11", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.11.tgz", + "integrity": "sha512-FdKZGPd8qmC3ZNke7CNhzcEgToc02M6WYZc9hcBsNQ17bgAd3s9F//1bDDYgMVBYxDM71V0sv/hBHlOY4I1ZVA==", "dependencies": { - "@babel/runtime": "^7.22.5", + "@babel/runtime": "^7.22.6", "@emotion/is-prop-valid": "^1.2.1", "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.7", + "@mui/utils": "^5.14.5", "@popperjs/core": "^2.11.8", - "clsx": "^1.2.1", + "clsx": "^2.0.0", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -3061,10 +3062,18 @@ } } }, + "node_modules/@mui/base/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.7.tgz", - "integrity": "sha512-/suIo4WoeL/OyO3KUsFVpdOmKiSAr6NpWXmQ4WLSxwKrTiha1FJxM6vwAki5W/5kR9WnVLw5E8JC4oHHsutT8w==", + "version": "5.14.5", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.5.tgz", + "integrity": "sha512-+wpGH1USwPcKMFPMvXqYPC6fEvhxM3FzxC8lyDiNK/imLyyJ6y2DPb1Oue7OGIKJWBmYBqrWWtfovrxd1aJHTA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" @@ -3095,19 +3104,68 @@ } } }, - "node_modules/@mui/material": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.7.tgz", - "integrity": "sha512-+n453jDDm88zZM3b5YK29nZ7gXY+s+rryH9ovDbhmfSkOlFtp+KSqbXy5cTaC/UlDqDM7sYYJGq8BmJov3v9Tg==", + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.140", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.140.tgz", + "integrity": "sha512-k75jos6jklCD8tA20PAK2H4RSCKycTcR4Pbfz7JbdxIkWXJ+y2MRalwMcen1vpB99v0yZHNUo6BtGz6rvs2jlQ==", "dependencies": { - "@babel/runtime": "^7.22.5", - "@mui/base": "5.0.0-beta.6", - "@mui/core-downloads-tracker": "^5.13.7", - "@mui/system": "^5.13.7", + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.11", + "@mui/system": "^5.14.5", "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.7", + "@mui/utils": "^5.14.5", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@mui/material": { + "version": "5.14.5", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.5.tgz", + "integrity": "sha512-4qa4GMfuZH0Ai3mttk5ccXP8a3sf7aPlAJwyMrUSz6h9hPri6BPou94zeu3rENhhmKLby9S/W1y+pmficy8JKA==", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.11", + "@mui/core-downloads-tracker": "^5.14.5", + "@mui/system": "^5.14.5", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.5", "@types/react-transition-group": "^4.4.6", - "clsx": "^1.2.1", + "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1", "react-is": "^18.2.0", @@ -3139,13 +3197,21 @@ } } }, + "node_modules/@mui/material/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/private-theming": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.7.tgz", - "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==", + "version": "5.14.5", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.5.tgz", + "integrity": "sha512-cC4C5RrpXpDaaZyH9QwmPhRLgz+f2SYbOty3cPkk4qPSOSfif2ZEcDD9HTENKDDd9deB+xkPKzzZhi8cxIx8Ig==", "dependencies": { - "@babel/runtime": "^7.22.5", - "@mui/utils": "^5.13.7", + "@babel/runtime": "^7.22.6", + "@mui/utils": "^5.14.5", "prop-types": "^15.8.1" }, "engines": { @@ -3197,16 +3263,16 @@ } }, "node_modules/@mui/system": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.7.tgz", - "integrity": "sha512-7R2KdI6vr8KtnauEfg9e9xQmPk6Gg/1vGNiALYyhSI+cYztxN6WmlSqGX4bjWn/Sygp1TUE1jhFEgs7MWruhkQ==", + "version": "5.14.5", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.5.tgz", + "integrity": "sha512-mextXZHDeGcR7E1kx43TRARrVXy+gI4wzpUgNv7MqZs1dvTVXQGVeAT6ydj9d6FUqHBPMNLGV/21vJOrpqsL+w==", "dependencies": { - "@babel/runtime": "^7.22.5", - "@mui/private-theming": "^5.13.7", + "@babel/runtime": "^7.22.6", + "@mui/private-theming": "^5.14.5", "@mui/styled-engine": "^5.13.2", "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.7", - "clsx": "^1.2.1", + "@mui/utils": "^5.14.5", + "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" }, @@ -3235,6 +3301,14 @@ } } }, + "node_modules/@mui/system/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/types": { "version": "7.2.4", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", @@ -3249,11 +3323,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.7.tgz", - "integrity": "sha512-/3BLptG/q0u36eYED7Nhf4fKXmcKb6LjjT7ZMwhZIZSdSxVqDqSTmATW3a56n3KEPQUXCU9TpxAfCBQhs6brVA==", + "version": "5.14.5", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.5.tgz", + "integrity": "sha512-6Hzw63VR9C5xYv+CbjndoRLU6Gntal8rJ5W+GUzkyHrGWIyYPWZPa6AevnyGioySNETATe1H9oXS8f/7qgIHJA==", "dependencies": { - "@babel/runtime": "^7.22.5", + "@babel/runtime": "^7.22.6", "@types/prop-types": "^15.7.5", "@types/react-is": "^18.2.1", "prop-types": "^15.8.1", diff --git a/geneit_app/package.json b/geneit_app/package.json index 9323da8..d0e704c 100644 --- a/geneit_app/package.json +++ b/geneit_app/package.json @@ -10,7 +10,8 @@ "@mdi/js": "^7.2.96", "@mdi/react": "^1.6.1", "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.4", + "@mui/lab": "^5.0.0-alpha.140", + "@mui/material": "^5.14.5", "@mui/x-data-grid": "^6.9.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", diff --git a/geneit_app/src/api/CoupleApi.ts b/geneit_app/src/api/CoupleApi.ts index 4944c98..9f651fc 100644 --- a/geneit_app/src/api/CoupleApi.ts +++ b/geneit_app/src/api/CoupleApi.ts @@ -1,6 +1,5 @@ import { APIClient } from "./ApiClient"; import { DateValue, Member } from "./MemberApi"; -import { ServerApi } from "./ServerApi"; interface CoupleApiInterface { id: number; diff --git a/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx b/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx index 759ef8a..a621a62 100644 --- a/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx @@ -20,6 +20,7 @@ import { import { useFamily } from "../../widgets/BaseFamilyRoute"; import { MemberItem } from "../../widgets/MemberItem"; import { RouterLink } from "../../widgets/RouterLink"; +import { BasicFamilyTree } from "../../widgets/BasicFamilyTree"; enum CurrTab { BasicTree, @@ -116,7 +117,13 @@ export function FamilyMemberTreeRoute(): React.ReactElement { {/* the tree itself */} - todo + + {currTab === CurrTab.BasicTree ? ( + + ) : ( + <>todo + )} + ); } diff --git a/geneit_app/src/widgets/BasicFamilyTree.tsx b/geneit_app/src/widgets/BasicFamilyTree.tsx new file mode 100644 index 0000000..a31a6d9 --- /dev/null +++ b/geneit_app/src/widgets/BasicFamilyTree.tsx @@ -0,0 +1,81 @@ +import { TreeItem, TreeView } from "@mui/lab"; +import { FamilyTreeNode } from "../utils/family_tree"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import ChevronRightIcon from "@mui/icons-material/ChevronRight"; +import React from "react"; +import { MemberPhoto } from "./MemberPhoto"; +import { Member, fmtDate } from "../api/MemberApi"; +import Icon from "@mdi/react"; +import { mdiCross } from "@mdi/js"; + +export function BasicFamilyTree(p: { + tree: FamilyTreeNode; +}): React.ReactElement { + return ( + } + defaultExpandIcon={} + sx={{ flexGrow: 1 }} + > + + + ); +} + +function FamilyTreeItem(p: { n: FamilyTreeNode }): React.ReactElement { + let children = p.n.down ?? []; + + if (p.n.couples) { + for (const c of p.n.couples) { + children = children.concat(c.down); + } + } + + return ( + + + + {p.n.couples?.map((c, n) => ( + + + + ))} + + } + > + {children.map((c) => ( + + ))} + + ); +} + +function BasicFamilyMemberItem(p: { + member: Member; + primary?: boolean; +}): React.ReactElement { + return ( +
+ + +
+ + {p.member.fullName}{" "} + {p.member?.dead && } + + {(p.member.dateOfBirth || p.member.dateOfDeath) && + fmtDate(p.member.dateOfBirth) + + (p.member.dateOfDeath ? " - " + fmtDate(p.member.dateOfDeath) : "")} +
+
+ ); +}