From cd7462ffb1b4ffaa89089eca3969e8743854717a Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 18:27:48 +0200 Subject: [PATCH 01/15] Refactor API routes --- geneit_app/src/api/FamilyApi.ts | 2 +- .../src/api/{ => genealogy}/CoupleApi.ts | 18 ++++----- geneit_app/src/api/{ => genealogy}/DataApi.ts | 6 +-- .../src/api/{ => genealogy}/MemberApi.ts | 16 ++++---- .../src/routes/family/FamilyCoupleRoute.tsx | 4 +- .../routes/family/FamilyCouplesListRoute.tsx | 4 +- .../src/routes/family/FamilyMemberRoute.tsx | 4 +- .../routes/family/FamilyMembersListRoute.tsx | 7 +++- .../src/routes/family/FamilySettingsRoute.tsx | 2 +- geneit_app/src/utils/family_tree.ts | 4 +- geneit_app/src/widgets/BaseFamilyRoute.tsx | 4 +- geneit_app/src/widgets/BasicFamilyTree.tsx | 4 +- geneit_app/src/widgets/CouplePhoto.tsx | 2 +- geneit_app/src/widgets/MemberItem.tsx | 2 +- geneit_app/src/widgets/MemberPhoto.tsx | 2 +- geneit_app/src/widgets/forms/DateInput.tsx | 2 +- geneit_app/src/widgets/forms/MemberInput.tsx | 2 +- geneit_app/src/widgets/forms/SexSelection.tsx | 2 +- .../simple_family_tree/SimpleFamilyTree.tsx | 4 +- geneit_backend/src/main.rs | 38 +++++++++---------- 20 files changed, 67 insertions(+), 62 deletions(-) rename geneit_app/src/api/{ => genealogy}/CoupleApi.ts (90%) rename geneit_app/src/api/{ => genealogy}/DataApi.ts (78%) rename geneit_app/src/api/{ => genealogy}/MemberApi.ts (94%) diff --git a/geneit_app/src/api/FamilyApi.ts b/geneit_app/src/api/FamilyApi.ts index 1518cac..94128c0 100644 --- a/geneit_app/src/api/FamilyApi.ts +++ b/geneit_app/src/api/FamilyApi.ts @@ -1,6 +1,6 @@ import { APIClient } from "./ApiClient"; import { Couple } from "./CoupleApi"; -import { Member } from "./MemberApi"; +import { Member } from "./genealogy/MemberApi"; interface FamilyAPI { user_id: number; diff --git a/geneit_app/src/api/CoupleApi.ts b/geneit_app/src/api/genealogy/CoupleApi.ts similarity index 90% rename from geneit_app/src/api/CoupleApi.ts rename to geneit_app/src/api/genealogy/CoupleApi.ts index 41234bd..bb12ae3 100644 --- a/geneit_app/src/api/CoupleApi.ts +++ b/geneit_app/src/api/genealogy/CoupleApi.ts @@ -1,6 +1,6 @@ -import { APIClient } from "./ApiClient"; +import { APIClient } from "../ApiClient"; import { DateValue, Member } from "./MemberApi"; -import { ServerApi } from "./ServerApi"; +import { ServerApi } from "../ServerApi"; interface CoupleApiInterface { id: number; @@ -161,7 +161,7 @@ export class CoupleApi { */ static async Create(m: Couple): Promise { const res = await APIClient.exec({ - uri: `/family/${m.family_id}/couple/create`, + uri: `/family/${m.family_id}/genealogy/couple/create`, method: "POST", jsonData: m, }); @@ -177,7 +177,7 @@ export class CoupleApi { couple_id: number ): Promise { const res = await APIClient.exec({ - uri: `/family/${family_id}/couple/${couple_id}`, + uri: `/family/${family_id}/genealogy/couple/${couple_id}`, method: "GET", }); @@ -189,7 +189,7 @@ export class CoupleApi { */ static async GetEntireList(family_id: number): Promise { const res = await APIClient.exec({ - uri: `/family/${family_id}/couples`, + uri: `/family/${family_id}/genealogy/couples`, method: "GET", }); @@ -201,7 +201,7 @@ export class CoupleApi { */ static async Update(m: Couple): Promise { await APIClient.exec({ - uri: `/family/${m.family_id}/couple/${m.id}`, + uri: `/family/${m.family_id}/genealogy/couple/${m.id}`, method: "PUT", jsonData: m, }); @@ -214,7 +214,7 @@ export class CoupleApi { const fd = new FormData(); fd.append("photo", b); await APIClient.exec({ - uri: `/family/${m.family_id}/couple/${m.id}/photo`, + uri: `/family/${m.family_id}/genealogy/couple/${m.id}/photo`, method: "PUT", formData: fd, }); @@ -225,7 +225,7 @@ export class CoupleApi { */ static async RemoveCouplePhoto(m: Couple): Promise { await APIClient.exec({ - uri: `/family/${m.family_id}/couple/${m.id}/photo`, + uri: `/family/${m.family_id}/genealogy/couple/${m.id}/photo`, method: "DELETE", }); } @@ -235,7 +235,7 @@ export class CoupleApi { */ static async Delete(m: Couple): Promise { await APIClient.exec({ - uri: `/family/${m.family_id}/couple/${m.id}`, + uri: `/family/${m.family_id}/genealogy/couple/${m.id}`, method: "DELETE", }); } diff --git a/geneit_app/src/api/DataApi.ts b/geneit_app/src/api/genealogy/DataApi.ts similarity index 78% rename from geneit_app/src/api/DataApi.ts rename to geneit_app/src/api/genealogy/DataApi.ts index 2b9a735..2c5281d 100644 --- a/geneit_app/src/api/DataApi.ts +++ b/geneit_app/src/api/genealogy/DataApi.ts @@ -1,4 +1,4 @@ -import { APIClient } from "./ApiClient"; +import { APIClient } from "../ApiClient"; /** * Data management api client @@ -9,7 +9,7 @@ export class DataApi { */ static async ExportData(family_id: number): Promise { const res = await APIClient.exec({ - uri: `/family/${family_id}/data/export`, + uri: `/family/${family_id}/genealogy/data/export`, method: "GET", }); return res.data; @@ -22,7 +22,7 @@ export class DataApi { const fd = new FormData(); fd.append("archive", archive); const res = await APIClient.exec({ - uri: `/family/${family_id}/data/import`, + uri: `/family/${family_id}/genealogy/data/import`, method: "PUT", formData: fd, }); diff --git a/geneit_app/src/api/MemberApi.ts b/geneit_app/src/api/genealogy/MemberApi.ts similarity index 94% rename from geneit_app/src/api/MemberApi.ts rename to geneit_app/src/api/genealogy/MemberApi.ts index 66b0d73..db989ab 100644 --- a/geneit_app/src/api/MemberApi.ts +++ b/geneit_app/src/api/genealogy/MemberApi.ts @@ -1,4 +1,4 @@ -import { APIClient } from "./ApiClient"; +import { APIClient } from "../ApiClient"; import { Couple } from "./CoupleApi"; export type Sex = "M" | "F"; @@ -278,7 +278,7 @@ export class MemberApi { */ static async Create(m: Member): Promise { const res = await APIClient.exec({ - uri: `/family/${m.family_id}/member/create`, + uri: `/family/${m.family_id}/genealogy/member/create`, method: "POST", jsonData: m, }); @@ -294,7 +294,7 @@ export class MemberApi { member_id: number ): Promise { const res = await APIClient.exec({ - uri: `/family/${family_id}/member/${member_id}`, + uri: `/family/${family_id}/genealogy/member/${member_id}`, method: "GET", }); @@ -306,7 +306,7 @@ export class MemberApi { */ static async GetEntireList(family_id: number): Promise { const res = await APIClient.exec({ - uri: `/family/${family_id}/members`, + uri: `/family/${family_id}/genealogy/members`, method: "GET", }); @@ -318,7 +318,7 @@ export class MemberApi { */ static async Update(m: Member): Promise { await APIClient.exec({ - uri: `/family/${m.family_id}/member/${m.id}`, + uri: `/family/${m.family_id}/genealogy/member/${m.id}`, method: "PUT", jsonData: m, }); @@ -331,7 +331,7 @@ export class MemberApi { const fd = new FormData(); fd.append("photo", b); await APIClient.exec({ - uri: `/family/${m.family_id}/member/${m.id}/photo`, + uri: `/family/${m.family_id}/genealogy/member/${m.id}/photo`, method: "PUT", formData: fd, }); @@ -342,7 +342,7 @@ export class MemberApi { */ static async RemoveMemberPhoto(m: Member): Promise { await APIClient.exec({ - uri: `/family/${m.family_id}/member/${m.id}/photo`, + uri: `/family/${m.family_id}/genealogy/member/${m.id}/photo`, method: "DELETE", }); } @@ -352,7 +352,7 @@ export class MemberApi { */ static async Delete(m: Member): Promise { await APIClient.exec({ - uri: `/family/${m.family_id}/member/${m.id}`, + uri: `/family/${m.family_id}/genealogy/member/${m.id}`, method: "DELETE", }); } diff --git a/geneit_app/src/routes/family/FamilyCoupleRoute.tsx b/geneit_app/src/routes/family/FamilyCoupleRoute.tsx index 172e870..3de9873 100644 --- a/geneit_app/src/routes/family/FamilyCoupleRoute.tsx +++ b/geneit_app/src/routes/family/FamilyCoupleRoute.tsx @@ -6,8 +6,8 @@ import SaveIcon from "@mui/icons-material/Save"; import { Button, Grid, Stack } from "@mui/material"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { Couple, CoupleApi } from "../../api/CoupleApi"; -import { Member } from "../../api/MemberApi"; +import { Couple, CoupleApi } from "../../api/genealogy/CoupleApi"; +import { Member } from "../../api/genealogy/MemberApi"; import { ServerApi } from "../../api/ServerApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; diff --git a/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx b/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx index c34c1f1..41d1a53 100644 --- a/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx +++ b/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx @@ -6,8 +6,8 @@ import { Button, TextField, Tooltip } from "@mui/material"; import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { Couple, CoupleApi } from "../../api/CoupleApi"; -import { dateTimestamp, fmtDate } from "../../api/MemberApi"; +import { Couple, CoupleApi } from "../../api/genealogy/CoupleApi"; +import { dateTimestamp, fmtDate } from "../../api/genealogy/MemberApi"; import { ServerApi } from "../../api/ServerApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; diff --git a/geneit_app/src/routes/family/FamilyMemberRoute.tsx b/geneit_app/src/routes/family/FamilyMemberRoute.tsx index 7502189..c394f53 100644 --- a/geneit_app/src/routes/family/FamilyMemberRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMemberRoute.tsx @@ -14,8 +14,8 @@ import { import * as EmailValidator from "email-validator"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { Couple } from "../../api/CoupleApi"; -import { Member, MemberApi, fmtDate } from "../../api/MemberApi"; +import { Couple } from "../../api/genealogy/CoupleApi"; +import { Member, MemberApi, fmtDate } from "../../api/genealogy/MemberApi"; import { ServerApi } from "../../api/ServerApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; diff --git a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx b/geneit_app/src/routes/family/FamilyMembersListRoute.tsx index 49cc89a..25dcffc 100644 --- a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMembersListRoute.tsx @@ -8,7 +8,12 @@ import { Button, TextField, Tooltip, Typography } from "@mui/material"; import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { Member, MemberApi, dateTimestamp, fmtDate } from "../../api/MemberApi"; +import { + Member, + MemberApi, + dateTimestamp, + fmtDate, +} from "../../api/genealogy/MemberApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; diff --git a/geneit_app/src/routes/family/FamilySettingsRoute.tsx b/geneit_app/src/routes/family/FamilySettingsRoute.tsx index 9f98d70..c99cfbd 100644 --- a/geneit_app/src/routes/family/FamilySettingsRoute.tsx +++ b/geneit_app/src/routes/family/FamilySettingsRoute.tsx @@ -14,7 +14,7 @@ import { } from "@mui/material"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { DataApi } from "../../api/DataApi"; +import { DataApi } from "../../api/genealogy/DataApi"; import { FamilyApi } from "../../api/FamilyApi"; import { ServerApi } from "../../api/ServerApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; diff --git a/geneit_app/src/utils/family_tree.ts b/geneit_app/src/utils/family_tree.ts index 5444540..62c9167 100644 --- a/geneit_app/src/utils/family_tree.ts +++ b/geneit_app/src/utils/family_tree.ts @@ -1,5 +1,5 @@ -import { Couple, CouplesList } from "../api/CoupleApi"; -import { Member, MembersList, dateTimestamp } from "../api/MemberApi"; +import { Couple, CouplesList } from "../api/genealogy/CoupleApi"; +import { Member, MembersList, dateTimestamp } from "../api/genealogy/MemberApi"; export interface CoupleInformation { couple: Couple; diff --git a/geneit_app/src/widgets/BaseFamilyRoute.tsx b/geneit_app/src/widgets/BaseFamilyRoute.tsx index 178b6d4..6f83a03 100644 --- a/geneit_app/src/widgets/BaseFamilyRoute.tsx +++ b/geneit_app/src/widgets/BaseFamilyRoute.tsx @@ -26,9 +26,9 @@ import { } from "@mui/material"; import React from "react"; import { Outlet, useLocation, useParams } from "react-router-dom"; -import { CoupleApi, CouplesList } from "../api/CoupleApi"; +import { CoupleApi, CouplesList } from "../api/genealogy/CoupleApi"; import { ExtendedFamilyInfo, FamilyApi } from "../api/FamilyApi"; -import { MemberApi, MembersList } from "../api/MemberApi"; +import { MemberApi, MembersList } from "../api/genealogy/MemberApi"; import { useAlert } from "../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider"; import { useSnackbar } from "../hooks/context_providers/SnackbarProvider"; diff --git a/geneit_app/src/widgets/BasicFamilyTree.tsx b/geneit_app/src/widgets/BasicFamilyTree.tsx index eb450ae..87a2e3f 100644 --- a/geneit_app/src/widgets/BasicFamilyTree.tsx +++ b/geneit_app/src/widgets/BasicFamilyTree.tsx @@ -5,8 +5,8 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { TreeItem, SimpleTreeView } from "@mui/x-tree-view"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { Couple } from "../api/CoupleApi"; -import { Member, fmtDate } from "../api/MemberApi"; +import { Couple } from "../api/genealogy/CoupleApi"; +import { Member, fmtDate } from "../api/genealogy/MemberApi"; import { FamilyTreeNode } from "../utils/family_tree"; import { useFamily } from "./BaseFamilyRoute"; import { MemberPhoto } from "./MemberPhoto"; diff --git a/geneit_app/src/widgets/CouplePhoto.tsx b/geneit_app/src/widgets/CouplePhoto.tsx index 059733f..323aef6 100644 --- a/geneit_app/src/widgets/CouplePhoto.tsx +++ b/geneit_app/src/widgets/CouplePhoto.tsx @@ -1,5 +1,5 @@ import { Avatar } from "@mui/material"; -import { Couple } from "../api/CoupleApi"; +import { Couple } from "../api/genealogy/CoupleApi"; export function CouplePhoto(p: { couple: Couple; diff --git a/geneit_app/src/widgets/MemberItem.tsx b/geneit_app/src/widgets/MemberItem.tsx index 0865076..99e11eb 100644 --- a/geneit_app/src/widgets/MemberItem.tsx +++ b/geneit_app/src/widgets/MemberItem.tsx @@ -5,7 +5,7 @@ import { ListItemSecondaryAction, ListItemText, } from "@mui/material"; -import { Member, fmtDate } from "../api/MemberApi"; +import { Member, fmtDate } from "../api/genealogy/MemberApi"; import { MemberPhoto } from "./MemberPhoto"; import Icon from "@mdi/react"; import FemaleIcon from "@mui/icons-material/Female"; diff --git a/geneit_app/src/widgets/MemberPhoto.tsx b/geneit_app/src/widgets/MemberPhoto.tsx index 5e19f06..fdbbf73 100644 --- a/geneit_app/src/widgets/MemberPhoto.tsx +++ b/geneit_app/src/widgets/MemberPhoto.tsx @@ -1,5 +1,5 @@ import { Avatar } from "@mui/material"; -import { Member } from "../api/MemberApi"; +import { Member } from "../api/genealogy/MemberApi"; export function MemberPhoto(p: { member?: Member; diff --git a/geneit_app/src/widgets/forms/DateInput.tsx b/geneit_app/src/widgets/forms/DateInput.tsx index 363aefa..64bdab9 100644 --- a/geneit_app/src/widgets/forms/DateInput.tsx +++ b/geneit_app/src/widgets/forms/DateInput.tsx @@ -1,6 +1,6 @@ import { Stack, TextField, Typography } from "@mui/material"; import { NumberConstraint, ServerApi } from "../../api/ServerApi"; -import { DateValue, fmtDate } from "../../api/MemberApi"; +import { DateValue, fmtDate } from "../../api/genealogy/MemberApi"; import { PropEdit } from "./PropEdit"; export function DateInput(p: { diff --git a/geneit_app/src/widgets/forms/MemberInput.tsx b/geneit_app/src/widgets/forms/MemberInput.tsx index 54c37e5..d35d212 100644 --- a/geneit_app/src/widgets/forms/MemberInput.tsx +++ b/geneit_app/src/widgets/forms/MemberInput.tsx @@ -2,7 +2,7 @@ import ClearIcon from "@mui/icons-material/Clear"; import { Autocomplete, IconButton, TextField, Typography } from "@mui/material"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { Member } from "../../api/MemberApi"; +import { Member } from "../../api/genealogy/MemberApi"; import { useFamily } from "../BaseFamilyRoute"; import { MemberItem } from "../MemberItem"; diff --git a/geneit_app/src/widgets/forms/SexSelection.tsx b/geneit_app/src/widgets/forms/SexSelection.tsx index 49f53e5..941379f 100644 --- a/geneit_app/src/widgets/forms/SexSelection.tsx +++ b/geneit_app/src/widgets/forms/SexSelection.tsx @@ -6,7 +6,7 @@ import { Radio, Typography, } from "@mui/material"; -import { Sex } from "../../api/MemberApi"; +import { Sex } from "../../api/genealogy/MemberApi"; export function SexSelection(p: { readonly?: boolean; diff --git a/geneit_app/src/widgets/simple_family_tree/SimpleFamilyTree.tsx b/geneit_app/src/widgets/simple_family_tree/SimpleFamilyTree.tsx index e13c041..c784dc2 100644 --- a/geneit_app/src/widgets/simple_family_tree/SimpleFamilyTree.tsx +++ b/geneit_app/src/widgets/simple_family_tree/SimpleFamilyTree.tsx @@ -5,8 +5,8 @@ import { IconButton, Tooltip } from "@mui/material"; import jsPDF from "jspdf"; import React from "react"; import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch"; -import { Couple } from "../../api/CoupleApi"; -import { Member } from "../../api/MemberApi"; +import { Couple } from "../../api/genealogy/CoupleApi"; +import { Member } from "../../api/genealogy/MemberApi"; import { useDarkTheme } from "../../hooks/context_providers/DarkThemeProvider"; import { FamilyTreeNode } from "../../utils/family_tree"; import { downloadBlob } from "../../utils/files_utils"; diff --git a/geneit_backend/src/main.rs b/geneit_backend/src/main.rs index 711766b..683dfcb 100644 --- a/geneit_backend/src/main.rs +++ b/geneit_backend/src/main.rs @@ -137,71 +137,71 @@ async fn main() -> std::io::Result<()> { "/family/{id}/user/{user_id}", web::delete().to(families_controller::delete_membership), ) - // Members controller + // [GENEALOGY] Members controller .route( - "/family/{id}/member/create", + "/family/{id}/genealogy/member/create", web::post().to(members_controller::create), ) .route( - "/family/{id}/members", + "/family/{id}/genealogy/members", web::get().to(members_controller::get_all), ) .route( - "/family/{id}/member/{member_id}", + "/family/{id}/genealogy/member/{member_id}", web::get().to(members_controller::get_single), ) .route( - "/family/{id}/member/{member_id}", + "/family/{id}/genealogy/member/{member_id}", web::put().to(members_controller::update), ) .route( - "/family/{id}/member/{member_id}", + "/family/{id}/genealogy/member/{member_id}", web::delete().to(members_controller::delete), ) .route( - "/family/{id}/member/{member_id}/photo", + "/family/{id}/genealogy/member/{member_id}/photo", web::put().to(members_controller::set_photo), ) .route( - "/family/{id}/member/{member_id}/photo", + "/family/{id}/genealogy/member/{member_id}/photo", web::delete().to(members_controller::remove_photo), ) - // Couples controller + // [GENEALOGY] Couples controller .route( - "/family/{id}/couple/create", + "/family/{id}/genealogy/couple/create", web::post().to(couples_controller::create), ) .route( - "/family/{id}/couples", + "/family/{id}/genealogy/couples", web::get().to(couples_controller::get_all), ) .route( - "/family/{id}/couple/{couple_id}", + "/family/{id}/genealogy/couple/{couple_id}", web::get().to(couples_controller::get_single), ) .route( - "/family/{id}/couple/{couple_id}", + "/family/{id}/genealogy/couple/{couple_id}", web::put().to(couples_controller::update), ) .route( - "/family/{id}/couple/{couple_id}", + "/family/{id}/genealogy/couple/{couple_id}", web::delete().to(couples_controller::delete), ) .route( - "/family/{id}/couple/{couple_id}/photo", + "/family/{id}/genealogy/couple/{couple_id}/photo", web::put().to(couples_controller::set_photo), ) .route( - "/family/{id}/couple/{couple_id}/photo", + "/family/{id}/genealogy/couple/{couple_id}/photo", web::delete().to(couples_controller::remove_photo), ) - // Data controller + // [GENEALOGY] Data controller .route( - "/family/{id}/data/export", + "/family/{id}/genealogy/data/export", web::get().to(data_controller::export_family), ) .route( - "/family/{id}/data/import", + "/family/{id}/genealogy/data/import", web::put().to(data_controller::import_family), ) // Photos controller -- 2.45.2 From c6b518d8de004bfb6f25e68858d645fbdda0898b Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 18:40:00 +0200 Subject: [PATCH 02/15] Fix icons alignment --- geneit_app/src/routes/family/FamilyCouplesListRoute.tsx | 8 +++++++- geneit_app/src/routes/family/FamilyMembersListRoute.tsx | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx b/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx index 41d1a53..4878c5c 100644 --- a/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx +++ b/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx @@ -132,7 +132,13 @@ function CouplesTable(p: { sortable: false, width: 60, renderCell(params) { - return ; + return ( +
+ +
+ ); }, }, diff --git a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx b/geneit_app/src/routes/family/FamilyMembersListRoute.tsx index 25dcffc..66a5af4 100644 --- a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMembersListRoute.tsx @@ -113,7 +113,13 @@ function MembersTable(p: { sortable: false, width: 60, renderCell(params) { - return ; + return ( +
+ +
+ ); }, }, -- 2.45.2 From 88e40fece6c315287e1cb9d3f102607341089a9b Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 18:56:18 +0200 Subject: [PATCH 03/15] Add a column in family table to toggle genealogy feature --- .../2024-05-15-164434_genealogy_as_feature/down.sql | 3 +++ .../migrations/2024-05-15-164434_genealogy_as_feature/up.sql | 5 +++++ geneit_backend/src/models.rs | 1 + geneit_backend/src/schema.rs | 1 + 4 files changed, 10 insertions(+) create mode 100644 geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/down.sql create mode 100644 geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/up.sql diff --git a/geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/down.sql b/geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/down.sql new file mode 100644 index 0000000..88da697 --- /dev/null +++ b/geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/down.sql @@ -0,0 +1,3 @@ +-- Remove column to toggle genealogy +ALTER TABLE public.families + DROP COLUMN enable_genealogy; \ No newline at end of file diff --git a/geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/up.sql b/geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/up.sql new file mode 100644 index 0000000..4238972 --- /dev/null +++ b/geneit_backend/migrations/2024-05-15-164434_genealogy_as_feature/up.sql @@ -0,0 +1,5 @@ +-- Add column to toggle genealogy +ALTER TABLE public.families + ADD enable_genealogy boolean NOT NULL DEFAULT false; +COMMENT +ON COLUMN public.families.enable_genealogy IS 'Specify whether genealogy feature is enabled for the family'; diff --git a/geneit_backend/src/models.rs b/geneit_backend/src/models.rs index e901fac..596d092 100644 --- a/geneit_backend/src/models.rs +++ b/geneit_backend/src/models.rs @@ -65,6 +65,7 @@ pub struct Family { pub name: String, pub invitation_code: String, pub disable_couple_photos: bool, + pub enable_genealogy: bool, } impl Family { diff --git a/geneit_backend/src/schema.rs b/geneit_backend/src/schema.rs index 708d30a..f681f84 100644 --- a/geneit_backend/src/schema.rs +++ b/geneit_backend/src/schema.rs @@ -29,6 +29,7 @@ diesel::table! { #[max_length = 7] invitation_code -> Varchar, disable_couple_photos -> Bool, + enable_genealogy -> Bool, } } -- 2.45.2 From d2a4bfb8e88860e3f115f3b2339b5cfdc5653143 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 19:05:45 +0200 Subject: [PATCH 04/15] Add genealogy setting --- geneit_app/src/api/FamilyApi.ts | 4 ++ .../src/routes/family/FamilySettingsRoute.tsx | 44 ++++++++++++++----- .../src/controllers/families_controller.rs | 4 ++ .../src/services/families_service.rs | 1 + 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/geneit_app/src/api/FamilyApi.ts b/geneit_app/src/api/FamilyApi.ts index 94128c0..1c3b929 100644 --- a/geneit_app/src/api/FamilyApi.ts +++ b/geneit_app/src/api/FamilyApi.ts @@ -85,9 +85,11 @@ export class Family implements FamilyAPI { export class ExtendedFamilyInfo extends Family { public disable_couple_photos: boolean; + public enable_genealogy: boolean; constructor(p: any) { super(p); this.disable_couple_photos = p.disable_couple_photos; + this.enable_genealogy = p.enable_genealogy; } } @@ -230,6 +232,7 @@ export class FamilyApi { static async UpdateFamily(settings: { id: number; name: string; + enable_genealogy: boolean; disable_couple_photos: boolean; }): Promise { await APIClient.exec({ @@ -237,6 +240,7 @@ export class FamilyApi { uri: `/family/${settings.id}`, jsonData: { name: settings.name, + enable_genealogy: settings.enable_genealogy, disable_couple_photos: settings.disable_couple_photos, }, }); diff --git a/geneit_app/src/routes/family/FamilySettingsRoute.tsx b/geneit_app/src/routes/family/FamilySettingsRoute.tsx index c99cfbd..5c1cc14 100644 --- a/geneit_app/src/routes/family/FamilySettingsRoute.tsx +++ b/geneit_app/src/routes/family/FamilySettingsRoute.tsx @@ -76,6 +76,9 @@ function FamilySettingsCard(): React.ReactElement { const family = useFamily(); const [newName, setNewName] = React.useState(family.family.name); + const [enableGenealogy, setEnableGenealogy] = React.useState( + family.family.enable_genealogy + ); const [disableCouplePhotos, setDisableCouplePhotos] = React.useState( family.family.disable_couple_photos ); @@ -93,6 +96,7 @@ function FamilySettingsCard(): React.ReactElement { await FamilyApi.UpdateFamily({ id: family.family.family_id, name: newName, + enable_genealogy: enableGenealogy, disable_couple_photos: disableCouplePhotos, }); @@ -144,18 +148,34 @@ function FamilySettingsCard(): React.ReactElement { maxLength: ServerApi.Config.constraints.family_name_len.max, }} /> - - setDisableCouplePhotos(c)} - /> - } - label="Désactiver les photos de couple" - /> - + + setEnableGenealogy(c)} + /> + } + label="Activer la généalogie" + /> + {enableGenealogy && ( + + setDisableCouplePhotos(c)} + /> + } + label="Désactiver les photos de couple" + /> + + )} diff --git a/geneit_backend/src/controllers/families_controller.rs b/geneit_backend/src/controllers/families_controller.rs index d5c3f92..1e37110 100644 --- a/geneit_backend/src/controllers/families_controller.rs +++ b/geneit_backend/src/controllers/families_controller.rs @@ -79,6 +79,7 @@ pub async fn list(token: LoginToken) -> HttpResult { struct RichFamilyInfo { #[serde(flatten)] membership: FamilyMembership, + enable_genealogy: bool, disable_couple_photos: bool, } @@ -88,6 +89,7 @@ pub async fn single_info(f: FamilyInPath) -> HttpResult { let family = families_service::get_by_id(f.family_id()).await?; Ok(HttpResponse::Ok().json(RichFamilyInfo { membership, + enable_genealogy: family.enable_genealogy, disable_couple_photos: family.disable_couple_photos, })) } @@ -102,6 +104,7 @@ pub async fn leave(f: FamilyInPath) -> HttpResult { #[derive(serde::Deserialize)] pub struct UpdateFamilyBody { name: String, + enable_genealogy: bool, disable_couple_photos: bool, } @@ -119,6 +122,7 @@ pub async fn update( let mut family = families_service::get_by_id(f.family_id()).await?; family.name = req.0.name; + family.enable_genealogy = req.0.enable_genealogy; family.disable_couple_photos = req.0.disable_couple_photos; families_service::update_family(&family).await?; diff --git a/geneit_backend/src/services/families_service.rs b/geneit_backend/src/services/families_service.rs index 77c6b0c..af6dd93 100644 --- a/geneit_backend/src/services/families_service.rs +++ b/geneit_backend/src/services/families_service.rs @@ -174,6 +174,7 @@ pub async fn update_family(family: &Family) -> anyhow::Result<()> { .set(( families::dsl::name.eq(family.name.clone()), families::dsl::invitation_code.eq(family.invitation_code.clone()), + families::dsl::enable_genealogy.eq(family.enable_genealogy), families::dsl::disable_couple_photos.eq(family.disable_couple_photos), )) .execute(conn) -- 2.45.2 From 299d52f5d700850a3080fea26013c12f1c4846cf Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 19:07:02 +0200 Subject: [PATCH 05/15] Fix error --- geneit_app/src/api/FamilyApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geneit_app/src/api/FamilyApi.ts b/geneit_app/src/api/FamilyApi.ts index 1c3b929..e830f54 100644 --- a/geneit_app/src/api/FamilyApi.ts +++ b/geneit_app/src/api/FamilyApi.ts @@ -1,5 +1,5 @@ import { APIClient } from "./ApiClient"; -import { Couple } from "./CoupleApi"; +import { Couple } from "./genealogy/CoupleApi"; import { Member } from "./genealogy/MemberApi"; interface FamilyAPI { -- 2.45.2 From 84ef4cac5350c09915b2803077c0b06c5466e1e7 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 19:36:57 +0200 Subject: [PATCH 06/15] Change all application routes --- geneit_app/src/App.tsx | 59 +++++++++++-------- geneit_app/src/api/FamilyApi.ts | 8 ++- .../src/routes/family/FamilyCoupleRoute.tsx | 6 +- .../src/routes/family/FamilyMemberRoute.tsx | 26 +++----- .../routes/family/FamilyMemberTreeRoute.tsx | 2 +- .../routes/family/FamilyMembersListRoute.tsx | 2 +- .../src/routes/family/FamilySettingsRoute.tsx | 8 +-- geneit_app/src/widgets/BaseFamilyRoute.tsx | 12 ++-- geneit_app/src/widgets/forms/MemberInput.tsx | 2 +- 9 files changed, 64 insertions(+), 61 deletions(-) diff --git a/geneit_app/src/App.tsx b/geneit_app/src/App.tsx index 2fdad99..8994ab5 100644 --- a/geneit_app/src/App.tsx +++ b/geneit_app/src/App.tsx @@ -67,33 +67,42 @@ export function App(): React.ReactElement { }> } /> - } /> - } - /> - } /> - } - /> + + } /> + } + /> + } + /> + } + /> - } /> - } - /> - } /> - } - /> + } /> + } + /> + } + /> + } + /> - } /> - } - /> + } /> + } + /> + } /> + } /> } /> diff --git a/geneit_app/src/api/FamilyApi.ts b/geneit_app/src/api/FamilyApi.ts index e830f54..763dc7e 100644 --- a/geneit_app/src/api/FamilyApi.ts +++ b/geneit_app/src/api/FamilyApi.ts @@ -60,7 +60,8 @@ export class Family implements FamilyAPI { */ memberURL(member: Member, edit?: boolean): string { return ( - `/family/${this.family_id}/member/${member.id}` + (edit ? "/edit" : "") + `/family/${this.family_id}/genealogy/member/${member.id}` + + (edit ? "/edit" : "") ); } @@ -68,7 +69,7 @@ export class Family implements FamilyAPI { * Get family tree URL for member */ familyTreeURL(member: Member | number): string { - return `/family/${this.family_id}/tree/${ + return `/family/${this.family_id}/genealogy/tree/${ typeof member === "number" ? member : member.id }`; } @@ -78,7 +79,8 @@ export class Family implements FamilyAPI { */ coupleURL(member: Couple, edit?: boolean): string { return ( - `/family/${this.family_id}/couple/${member.id}` + (edit ? "/edit" : "") + `/family/${this.family_id}/genealogy/couple/${member.id}` + + (edit ? "/edit" : "") ); } } diff --git a/geneit_app/src/routes/family/FamilyCoupleRoute.tsx b/geneit_app/src/routes/family/FamilyCoupleRoute.tsx index 3de9873..7693feb 100644 --- a/geneit_app/src/routes/family/FamilyCoupleRoute.tsx +++ b/geneit_app/src/routes/family/FamilyCoupleRoute.tsx @@ -62,7 +62,7 @@ export function FamilyCreateCoupleRoute(): React.ReactElement { const cancel = () => { setShouldQuit(true); - n(family.family.URL("couples")); + n(family.family.URL("genealogy/couples")); }; return ( @@ -115,7 +115,7 @@ export function FamilyCoupleRoute(): React.ReactElement { await CoupleApi.Delete(couple!); snackbar("La fiche du couple a été supprimée avec succès !"); - n(family.family.URL("couples")); + n(family.family.URL("genealogy/couples")); await family.reloadCouplesList(); } catch (e) { @@ -486,7 +486,7 @@ export function CouplePage(p: {
diff --git a/geneit_app/src/routes/family/FamilyMemberRoute.tsx b/geneit_app/src/routes/family/FamilyMemberRoute.tsx index c394f53..7e5509e 100644 --- a/geneit_app/src/routes/family/FamilyMemberRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMemberRoute.tsx @@ -63,7 +63,7 @@ export function FamilyCreateMemberRoute(): React.ReactElement { await family.reloadMembersList(); setShouldQuit(true); - n(family.family.URL(`member/${r.id}`)); + n(family.family.URL(`genealogy/member/${r.id}`)); snackbar(`La fiche pour ${r.fullName} a été créée avec succès !`); } catch (e) { console.error(e); @@ -73,7 +73,7 @@ export function FamilyCreateMemberRoute(): React.ReactElement { const cancel = () => { setShouldQuit(true); - n(family.family.URL("members")); + n(family.family.URL("genealogy/members")); }; const member = Member.New(family.family.family_id); @@ -130,7 +130,7 @@ export function FamilyMemberRoute(): React.ReactElement { await MemberApi.Delete(member!); snackbar("La fiche de membre a été supprimée avec succès !"); - n(family.family.URL("members")); + n(family.family.URL("genealogy/members")); await family.reloadMembersList(); } catch (e) { @@ -155,9 +155,7 @@ export function FamilyMemberRoute(): React.ReactElement { editing={false} onrequestOpenTree={() => n(family.family.familyTreeURL(member!))} onRequestDelete={deleteMember} - onRequestEdit={() => - n(family.family.URL(`member/${member!.id}/edit`)) - } + onRequestEdit={() => n(family.family.memberURL(member!, true))} onForceReload={forceReload} /> )} @@ -199,7 +197,7 @@ export function FamilyEditMemberRoute(): React.ReactElement { await family.reloadMembersList(); setShouldQuit(true); - n(family.family.URL(`member/${member!.id}`)); + n(family.family.memberURL(member!)); } catch (e) { console.error(e); alert("Échec de la mise à jour des informations du membre !"); @@ -682,10 +680,7 @@ export function MemberPage(p: { <>Aucun enfant ) : ( p.children.map((c) => ( - + )) @@ -694,7 +689,7 @@ export function MemberPage(p: {
Aucun frère ou sœur ) : ( p.siblings.map((c) => ( - + )) @@ -727,7 +719,7 @@ export function MemberPage(p: {
diff --git a/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx b/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx index faa24b6..5949f6b 100644 --- a/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx @@ -87,7 +87,7 @@ export function FamilyMemberTreeRoute(): React.ReactElement { dense member={member} secondary={ - + diff --git a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx b/geneit_app/src/routes/family/FamilyMembersListRoute.tsx index 66a5af4..db7a48a 100644 --- a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx +++ b/geneit_app/src/routes/family/FamilyMembersListRoute.tsx @@ -60,7 +60,7 @@ export function FamilyMembersListRoute(): React.ReactElement { }} > - + diff --git a/geneit_app/src/routes/family/FamilySettingsRoute.tsx b/geneit_app/src/routes/family/FamilySettingsRoute.tsx index 5c1cc14..bfc4186 100644 --- a/geneit_app/src/routes/family/FamilySettingsRoute.tsx +++ b/geneit_app/src/routes/family/FamilySettingsRoute.tsx @@ -14,9 +14,9 @@ import { } from "@mui/material"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { DataApi } from "../../api/genealogy/DataApi"; import { FamilyApi } from "../../api/FamilyApi"; import { ServerApi } from "../../api/ServerApi"; +import { DataApi } from "../../api/genealogy/DataApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider"; @@ -55,7 +55,7 @@ export function FamilySettingsRoute(): React.ReactElement { return ( <> - + {family.family.enable_genealogy && }
-- 2.45.2 From b59db99d020517882e00457127280750f9e02238 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 19:40:03 +0200 Subject: [PATCH 08/15] Change menu --- geneit_app/src/widgets/BaseFamilyRoute.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/geneit_app/src/widgets/BaseFamilyRoute.tsx b/geneit_app/src/widgets/BaseFamilyRoute.tsx index cd4f769..4f455e5 100644 --- a/geneit_app/src/widgets/BaseFamilyRoute.tsx +++ b/geneit_app/src/widgets/BaseFamilyRoute.tsx @@ -147,6 +147,9 @@ export function BaseFamilyRoute(): React.ReactElement { } label="Accueil" uri="" /> + + Généalogie + } label="Membres" -- 2.45.2 From 1daca27ba0665f205b2251e291e1ed70f62428b0 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 19:43:54 +0200 Subject: [PATCH 09/15] Start to divide application --- geneit_app/src/App.tsx | 3 +++ .../src/routes/family/FamilyHomeRoute.tsx | 7 ------- .../family/genealogy/GenealogyHomeRoute.tsx | 20 +++++++++++++++++++ geneit_app/src/widgets/BaseFamilyRoute.tsx | 5 +++++ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx diff --git a/geneit_app/src/App.tsx b/geneit_app/src/App.tsx index 8994ab5..6b9dcfe 100644 --- a/geneit_app/src/App.tsx +++ b/geneit_app/src/App.tsx @@ -36,6 +36,7 @@ import { import { FamilyCouplesListRoute } from "./routes/family/FamilyCouplesListRoute"; import { FamilyTreeRoute } from "./routes/family/FamilyTreeRoute"; import { FamilyMemberTreeRoute } from "./routes/family/FamilyMemberTreeRoute"; +import { GenealogyHomeRoute } from "./routes/family/genealogy/GenealogyHomeRoute"; interface AuthContext { signedIn: boolean; @@ -68,6 +69,8 @@ export function App(): React.ReactElement { } /> + } /> + } /> @@ -12,12 +11,6 @@ export function FamilyHomeRoute(): React.ReactElement { Veuillez utiliser le menu situé à gauche pour accéder aux différentes sections de l'application.

-

Nombre de fiches de membres: {family.members.size}

-

Nombre de fiches de couples: {family.couples.size}

-

- Vous pouvez inviter d'autres personnes à rejoindre cette famille en - leur donnant une copie du code d'invitation -

); diff --git a/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx b/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx new file mode 100644 index 0000000..37461af --- /dev/null +++ b/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx @@ -0,0 +1,20 @@ +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; + +export function GenealogyHomeRoute(): React.ReactElement { + const family = useFamily(); + return ( + <> + +
+

+ Depuis cette section de l'application, vous pouvez afficher et + compléter l'abre généalogique de votre famille. +

+

 

+

Nombre de fiches de membres: {family.members.size}

+

Nombre de fiches de couples: {family.couples.size}

+
+ + ); +} diff --git a/geneit_app/src/widgets/BaseFamilyRoute.tsx b/geneit_app/src/widgets/BaseFamilyRoute.tsx index 4f455e5..ca02be9 100644 --- a/geneit_app/src/widgets/BaseFamilyRoute.tsx +++ b/geneit_app/src/widgets/BaseFamilyRoute.tsx @@ -150,6 +150,11 @@ export function BaseFamilyRoute(): React.ReactElement { Généalogie + } + label="Accueil" + uri="genealogy" + /> } label="Membres" -- 2.45.2 From f686d3fcbf8f3b95dd65c1fe474bbbcd31832cc1 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 19:45:29 +0200 Subject: [PATCH 10/15] Refactor routes storage --- geneit_app/src/App.tsx | 14 +++--- .../{ => genealogy}/FamilyCoupleRoute.tsx | 40 ++++++++-------- .../FamilyCouplesListRoute.tsx | 22 ++++----- .../{ => genealogy}/FamilyHomeRoute.tsx | 4 +- .../{ => genealogy}/FamilyMemberRoute.tsx | 48 +++++++++---------- .../{ => genealogy}/FamilyMemberTreeRoute.tsx | 12 ++--- .../FamilyMembersListRoute.tsx | 16 +++---- .../{ => genealogy}/FamilyTreeRoute.tsx | 4 +- 8 files changed, 80 insertions(+), 80 deletions(-) rename geneit_app/src/routes/family/{ => genealogy}/FamilyCoupleRoute.tsx (90%) rename geneit_app/src/routes/family/{ => genealogy}/FamilyCouplesListRoute.tsx (90%) rename geneit_app/src/routes/family/{ => genealogy}/FamilyHomeRoute.tsx (76%) rename geneit_app/src/routes/family/{ => genealogy}/FamilyMemberRoute.tsx (92%) rename geneit_app/src/routes/family/{ => genealogy}/FamilyMemberTreeRoute.tsx (91%) rename geneit_app/src/routes/family/{ => genealogy}/FamilyMembersListRoute.tsx (91%) rename geneit_app/src/routes/family/{ => genealogy}/FamilyTreeRoute.tsx (87%) diff --git a/geneit_app/src/App.tsx b/geneit_app/src/App.tsx index 6b9dcfe..afb7f0f 100644 --- a/geneit_app/src/App.tsx +++ b/geneit_app/src/App.tsx @@ -16,26 +16,26 @@ import { NewAccountRoute } from "./routes/auth/NewAccountRoute"; import { OIDCCbRoute } from "./routes/auth/OIDCCbRoute"; import { PasswordForgottenRoute } from "./routes/auth/PasswordForgottenRoute"; import { ResetPasswordRoute } from "./routes/auth/ResetPasswordRoute"; -import { FamilyHomeRoute } from "./routes/family/FamilyHomeRoute"; +import { FamilyHomeRoute } from "./routes/family/genealogy/FamilyHomeRoute"; import { FamilyCreateMemberRoute, FamilyEditMemberRoute, FamilyMemberRoute, -} from "./routes/family/FamilyMemberRoute"; +} from "./routes/family/genealogy/FamilyMemberRoute"; import { FamilySettingsRoute } from "./routes/family/FamilySettingsRoute"; import { FamilyUsersListRoute } from "./routes/family/FamilyUsersListRoute"; import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage"; import { BaseFamilyRoute } from "./widgets/BaseFamilyRoute"; import { BaseLoginPage } from "./widgets/BaseLoginpage"; -import { FamilyMembersListRoute } from "./routes/family/FamilyMembersListRoute"; +import { FamilyMembersListRoute } from "./routes/family/genealogy/FamilyMembersListRoute"; import { FamilyCoupleRoute, FamilyCreateCoupleRoute, FamilyEditCoupleRoute, -} from "./routes/family/FamilyCoupleRoute"; -import { FamilyCouplesListRoute } from "./routes/family/FamilyCouplesListRoute"; -import { FamilyTreeRoute } from "./routes/family/FamilyTreeRoute"; -import { FamilyMemberTreeRoute } from "./routes/family/FamilyMemberTreeRoute"; +} from "./routes/family/genealogy/FamilyCoupleRoute"; +import { FamilyCouplesListRoute } from "./routes/family/genealogy/FamilyCouplesListRoute"; +import { FamilyTreeRoute } from "./routes/family/genealogy/FamilyTreeRoute"; +import { FamilyMemberTreeRoute } from "./routes/family/genealogy/FamilyMemberTreeRoute"; import { GenealogyHomeRoute } from "./routes/family/genealogy/GenealogyHomeRoute"; interface AuthContext { diff --git a/geneit_app/src/routes/family/FamilyCoupleRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx similarity index 90% rename from geneit_app/src/routes/family/FamilyCoupleRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx index 7693feb..d6774c5 100644 --- a/geneit_app/src/routes/family/FamilyCoupleRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx @@ -6,26 +6,26 @@ import SaveIcon from "@mui/icons-material/Save"; import { Button, Grid, Stack } from "@mui/material"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { Couple, CoupleApi } from "../../api/genealogy/CoupleApi"; -import { Member } from "../../api/genealogy/MemberApi"; -import { ServerApi } from "../../api/ServerApi"; -import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; -import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; -import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; -import { AsyncWidget } from "../../widgets/AsyncWidget"; -import { useFamily } from "../../widgets/BaseFamilyRoute"; -import { ConfirmLeaveWithoutSaveDialog } from "../../widgets/ConfirmLeaveWithoutSaveDialog"; -import { CouplePhoto } from "../../widgets/CouplePhoto"; -import { FamilyPageTitle } from "../../widgets/FamilyPageTitle"; -import { MemberItem } from "../../widgets/MemberItem"; -import { PropertiesBox } from "../../widgets/PropertiesBox"; -import { RouterLink } from "../../widgets/RouterLink"; -import { DateInput } from "../../widgets/forms/DateInput"; -import { MemberInput } from "../../widgets/forms/MemberInput"; -import { PropSelect } from "../../widgets/forms/PropSelect"; -import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton"; -import { useQuery } from "../../hooks/useQuery"; -import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider"; +import { Couple, CoupleApi } from "../../../api/genealogy/CoupleApi"; +import { Member } from "../../../api/genealogy/MemberApi"; +import { ServerApi } from "../../../api/ServerApi"; +import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; +import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; +import { AsyncWidget } from "../../../widgets/AsyncWidget"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { ConfirmLeaveWithoutSaveDialog } from "../../../widgets/ConfirmLeaveWithoutSaveDialog"; +import { CouplePhoto } from "../../../widgets/CouplePhoto"; +import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; +import { MemberItem } from "../../../widgets/MemberItem"; +import { PropertiesBox } from "../../../widgets/PropertiesBox"; +import { RouterLink } from "../../../widgets/RouterLink"; +import { DateInput } from "../../../widgets/forms/DateInput"; +import { MemberInput } from "../../../widgets/forms/MemberInput"; +import { PropSelect } from "../../../widgets/forms/PropSelect"; +import { UploadPhotoButton } from "../../../widgets/forms/UploadPhotoButton"; +import { useQuery } from "../../../hooks/useQuery"; +import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; /** * Create a new couple route diff --git a/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx similarity index 90% rename from geneit_app/src/routes/family/FamilyCouplesListRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx index 4878c5c..940b6bf 100644 --- a/geneit_app/src/routes/family/FamilyCouplesListRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx @@ -6,17 +6,17 @@ import { Button, TextField, Tooltip } from "@mui/material"; import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid"; import React from "react"; import { useNavigate } from "react-router-dom"; -import { Couple, CoupleApi } from "../../api/genealogy/CoupleApi"; -import { dateTimestamp, fmtDate } from "../../api/genealogy/MemberApi"; -import { ServerApi } from "../../api/ServerApi"; -import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; -import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; -import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; -import { useFamily } from "../../widgets/BaseFamilyRoute"; -import { CouplePhoto } from "../../widgets/CouplePhoto"; -import { FamilyPageTitle } from "../../widgets/FamilyPageTitle"; -import { MemberPhoto } from "../../widgets/MemberPhoto"; -import { RouterLink } from "../../widgets/RouterLink"; +import { Couple, CoupleApi } from "../../../api/genealogy/CoupleApi"; +import { dateTimestamp, fmtDate } from "../../../api/genealogy/MemberApi"; +import { ServerApi } from "../../../api/ServerApi"; +import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; +import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { CouplePhoto } from "../../../widgets/CouplePhoto"; +import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; +import { MemberPhoto } from "../../../widgets/MemberPhoto"; +import { RouterLink } from "../../../widgets/RouterLink"; export function FamilyCouplesListRoute(): React.ReactElement { const alert = useAlert(); diff --git a/geneit_app/src/routes/family/FamilyHomeRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyHomeRoute.tsx similarity index 76% rename from geneit_app/src/routes/family/FamilyHomeRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyHomeRoute.tsx index 3be1b65..4a66382 100644 --- a/geneit_app/src/routes/family/FamilyHomeRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyHomeRoute.tsx @@ -1,5 +1,5 @@ -import { useFamily } from "../../widgets/BaseFamilyRoute"; -import { FamilyPageTitle } from "../../widgets/FamilyPageTitle"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; export function FamilyHomeRoute(): React.ReactElement { return ( diff --git a/geneit_app/src/routes/family/FamilyMemberRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx similarity index 92% rename from geneit_app/src/routes/family/FamilyMemberRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx index 1e87d32..6d02ee6 100644 --- a/geneit_app/src/routes/family/FamilyMemberRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx @@ -14,32 +14,32 @@ import { import * as EmailValidator from "email-validator"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { Couple } from "../../api/genealogy/CoupleApi"; -import { Member, MemberApi, fmtDate } from "../../api/genealogy/MemberApi"; -import { ServerApi } from "../../api/ServerApi"; -import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; -import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; -import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; -import { AsyncWidget } from "../../widgets/AsyncWidget"; -import { useFamily } from "../../widgets/BaseFamilyRoute"; -import { ConfirmLeaveWithoutSaveDialog } from "../../widgets/ConfirmLeaveWithoutSaveDialog"; -import { CouplePhoto } from "../../widgets/CouplePhoto"; -import { FamilyPageTitle } from "../../widgets/FamilyPageTitle"; -import { MemberItem } from "../../widgets/MemberItem"; -import { MemberPhoto } from "../../widgets/MemberPhoto"; -import { PropertiesBox } from "../../widgets/PropertiesBox"; -import { RouterLink } from "../../widgets/RouterLink"; -import { DateInput } from "../../widgets/forms/DateInput"; -import { MemberInput } from "../../widgets/forms/MemberInput"; -import { PropCheckbox } from "../../widgets/forms/PropCheckbox"; -import { PropEdit } from "../../widgets/forms/PropEdit"; -import { PropSelect } from "../../widgets/forms/PropSelect"; -import { SexSelection } from "../../widgets/forms/SexSelection"; -import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton"; -import { useQuery } from "../../hooks/useQuery"; +import { Couple } from "../../../api/genealogy/CoupleApi"; +import { Member, MemberApi, fmtDate } from "../../../api/genealogy/MemberApi"; +import { ServerApi } from "../../../api/ServerApi"; +import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; +import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; +import { AsyncWidget } from "../../../widgets/AsyncWidget"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { ConfirmLeaveWithoutSaveDialog } from "../../../widgets/ConfirmLeaveWithoutSaveDialog"; +import { CouplePhoto } from "../../../widgets/CouplePhoto"; +import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; +import { MemberItem } from "../../../widgets/MemberItem"; +import { MemberPhoto } from "../../../widgets/MemberPhoto"; +import { PropertiesBox } from "../../../widgets/PropertiesBox"; +import { RouterLink } from "../../../widgets/RouterLink"; +import { DateInput } from "../../../widgets/forms/DateInput"; +import { MemberInput } from "../../../widgets/forms/MemberInput"; +import { PropCheckbox } from "../../../widgets/forms/PropCheckbox"; +import { PropEdit } from "../../../widgets/forms/PropEdit"; +import { PropSelect } from "../../../widgets/forms/PropSelect"; +import { SexSelection } from "../../../widgets/forms/SexSelection"; +import { UploadPhotoButton } from "../../../widgets/forms/UploadPhotoButton"; +import { useQuery } from "../../../hooks/useQuery"; import { mdiFamilyTree } from "@mdi/js"; import Icon from "@mdi/react"; -import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider"; +import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; /** * Create a new member route diff --git a/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx similarity index 91% rename from geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx index 5949f6b..ac3be15 100644 --- a/geneit_app/src/routes/family/FamilyMemberTreeRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx @@ -21,12 +21,12 @@ import { 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 { SimpleFamilyTree } from "../../widgets/simple_family_tree/SimpleFamilyTree"; +} 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 { SimpleFamilyTree } from "../../../widgets/simple_family_tree/SimpleFamilyTree"; enum CurrTab { BasicTree, diff --git a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx similarity index 91% rename from geneit_app/src/routes/family/FamilyMembersListRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx index db7a48a..425ddb4 100644 --- a/geneit_app/src/routes/family/FamilyMembersListRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx @@ -13,14 +13,14 @@ import { MemberApi, dateTimestamp, fmtDate, -} from "../../api/genealogy/MemberApi"; -import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; -import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; -import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider"; -import { useFamily } from "../../widgets/BaseFamilyRoute"; -import { FamilyPageTitle } from "../../widgets/FamilyPageTitle"; -import { MemberPhoto } from "../../widgets/MemberPhoto"; -import { RouterLink } from "../../widgets/RouterLink"; +} from "../../../api/genealogy/MemberApi"; +import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; +import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; +import { MemberPhoto } from "../../../widgets/MemberPhoto"; +import { RouterLink } from "../../../widgets/RouterLink"; export function FamilyMembersListRoute(): React.ReactElement { const alert = useAlert(); diff --git a/geneit_app/src/routes/family/FamilyTreeRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyTreeRoute.tsx similarity index 87% rename from geneit_app/src/routes/family/FamilyTreeRoute.tsx rename to geneit_app/src/routes/family/genealogy/FamilyTreeRoute.tsx index 86bda38..0e0a98e 100644 --- a/geneit_app/src/routes/family/FamilyTreeRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyTreeRoute.tsx @@ -1,6 +1,6 @@ import { useNavigate } from "react-router-dom"; -import { useFamily } from "../../widgets/BaseFamilyRoute"; -import { MemberInput } from "../../widgets/forms/MemberInput"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { MemberInput } from "../../../widgets/forms/MemberInput"; export function FamilyTreeRoute(): React.ReactElement { const n = useNavigate(); -- 2.45.2 From 7594913c260f094ee8606e41103e868136aa5a1a Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 21:38:43 +0200 Subject: [PATCH 11/15] WIP genealogy refactoring --- geneit_app/src/App.tsx | 3 +- .../widgets/genealogy/BaseGenealogyRoute.tsx | 73 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx diff --git a/geneit_app/src/App.tsx b/geneit_app/src/App.tsx index afb7f0f..1bb55f3 100644 --- a/geneit_app/src/App.tsx +++ b/geneit_app/src/App.tsx @@ -37,6 +37,7 @@ import { FamilyCouplesListRoute } from "./routes/family/genealogy/FamilyCouplesL import { FamilyTreeRoute } from "./routes/family/genealogy/FamilyTreeRoute"; import { FamilyMemberTreeRoute } from "./routes/family/genealogy/FamilyMemberTreeRoute"; import { GenealogyHomeRoute } from "./routes/family/genealogy/GenealogyHomeRoute"; +import { BaseGenealogyRoute } from "./widgets/genealogy/BaseGenealogyRoute"; interface AuthContext { signedIn: boolean; @@ -68,7 +69,7 @@ export function App(): React.ReactElement { }> } /> - + }> } /> } /> diff --git a/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx b/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx new file mode 100644 index 0000000..f2b1b3c --- /dev/null +++ b/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx @@ -0,0 +1,73 @@ +import React from "react"; +import { Outlet } from "react-router-dom"; +import { CoupleApi, CouplesList } from "../../api/genealogy/CoupleApi"; +import { MemberApi, MembersList } from "../../api/genealogy/MemberApi"; +import { AsyncWidget } from "../AsyncWidget"; +import { useFamily } from "../BaseFamilyRoute"; + +interface FamilyContext { + members: MembersList; + couples: CouplesList; + reloadMembersList: () => Promise; + reloadCouplesList: () => Promise; +} + +const GenealogyContextK = React.createContext(null); + +export function BaseGenealogyRoute(): React.ReactElement { + const family = useFamily(); + + const [members, setMembers] = React.useState(null); + const [couples, setCouples] = React.useState(null); + + const loadKey = React.useRef(1); + + const loadPromise = React.useRef<() => void>(); + + const load = async () => { + setMembers(await MemberApi.GetEntireList(family.familyId)); + setCouples(await CoupleApi.GetEntireList(family.familyId)); + }; + + const onReload = async () => { + loadKey.current += 1; + setMembers(null); + setCouples(null); + + return new Promise((res, _rej) => { + loadPromise.current = () => res(); + }); + }; + + return ( + { + if (loadPromise.current != null) { + loadPromise.current?.(); + loadPromise.current = undefined; + } + + return ( + + + + ); + }} + /> + ); +} + +export function useGenealogy(): FamilyContext { + return React.useContext(GenealogyContextK)!; +} -- 2.45.2 From 28b29d6cd643936beba3b8cd6c57a9f526f73aa5 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 15 May 2024 21:50:32 +0200 Subject: [PATCH 12/15] Load genealogy data only on genealogy pages --- .../family/genealogy/FamilyCoupleRoute.tsx | 20 +++++++----- .../genealogy/FamilyCouplesListRoute.tsx | 26 ++++++++++------ .../family/genealogy/FamilyMemberRoute.tsx | 31 +++++++++++-------- .../genealogy/FamilyMemberTreeRoute.tsx | 10 +++--- .../genealogy/FamilyMembersListRoute.tsx | 15 +++++---- .../family/genealogy/GenealogyHomeRoute.tsx | 8 ++--- geneit_app/src/widgets/BaseFamilyRoute.tsx | 18 +---------- geneit_app/src/widgets/forms/MemberInput.tsx | 8 +++-- .../widgets/genealogy/BaseGenealogyRoute.tsx | 2 +- 9 files changed, 72 insertions(+), 66 deletions(-) diff --git a/geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx index d6774c5..19e8f50 100644 --- a/geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyCoupleRoute.tsx @@ -6,12 +6,14 @@ import SaveIcon from "@mui/icons-material/Save"; import { Button, Grid, Stack } from "@mui/material"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; +import { ServerApi } from "../../../api/ServerApi"; import { Couple, CoupleApi } from "../../../api/genealogy/CoupleApi"; import { Member } from "../../../api/genealogy/MemberApi"; -import { ServerApi } from "../../../api/ServerApi"; import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; +import { useQuery } from "../../../hooks/useQuery"; import { AsyncWidget } from "../../../widgets/AsyncWidget"; import { useFamily } from "../../../widgets/BaseFamilyRoute"; import { ConfirmLeaveWithoutSaveDialog } from "../../../widgets/ConfirmLeaveWithoutSaveDialog"; @@ -24,8 +26,7 @@ import { DateInput } from "../../../widgets/forms/DateInput"; import { MemberInput } from "../../../widgets/forms/MemberInput"; import { PropSelect } from "../../../widgets/forms/PropSelect"; import { UploadPhotoButton } from "../../../widgets/forms/UploadPhotoButton"; -import { useQuery } from "../../../hooks/useQuery"; -import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; +import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute"; /** * Create a new couple route @@ -36,6 +37,7 @@ export function FamilyCreateCoupleRoute(): React.ReactElement { const [shouldQuit, setShouldQuit] = React.useState(false); const n = useNavigate(); + const genealogy = useGenealogy(); const family = useFamily(); const params = useQuery(); @@ -49,7 +51,7 @@ export function FamilyCreateCoupleRoute(): React.ReactElement { try { const r = await CoupleApi.Create(m); - await family.reloadCouplesList(); + await genealogy.reloadCouplesList(); setShouldQuit(true); n(family.family.coupleURL(r)); @@ -89,6 +91,7 @@ export function FamilyCoupleRoute(): React.ReactElement { const snackbar = useSnackbar(); const family = useFamily(); + const genealogy = useGenealogy(); const { coupleId } = useParams(); const [couple, setCouple] = React.useState(); @@ -100,7 +103,7 @@ export function FamilyCoupleRoute(): React.ReactElement { count.current += 1; setCouple(undefined); - await family.reloadCouplesList(); + await genealogy.reloadCouplesList(); }; const deleteCouple = async () => { @@ -117,7 +120,7 @@ export function FamilyCoupleRoute(): React.ReactElement { snackbar("La fiche du couple a été supprimée avec succès !"); n(family.family.URL("genealogy/couples")); - await family.reloadCouplesList(); + await genealogy.reloadCouplesList(); } catch (e) { console.error(e); alert("Échec de la suppression du couple !"); @@ -133,7 +136,7 @@ export function FamilyCoupleRoute(): React.ReactElement { build={() => ( (); @@ -176,7 +180,7 @@ export function FamilyEditCoupleRoute(): React.ReactElement { snackbar("Les informations du couple ont été mises à jour avec succès !"); - await family.reloadCouplesList(); + await genealogy.reloadCouplesList(); setShouldQuit(true); n(family.family.coupleURL(c, false)); diff --git a/geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx index 940b6bf..465f191 100644 --- a/geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyCouplesListRoute.tsx @@ -17,6 +17,7 @@ import { CouplePhoto } from "../../../widgets/CouplePhoto"; import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; import { MemberPhoto } from "../../../widgets/MemberPhoto"; import { RouterLink } from "../../../widgets/RouterLink"; +import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute"; export function FamilyCouplesListRoute(): React.ReactElement { const alert = useAlert(); @@ -24,6 +25,7 @@ export function FamilyCouplesListRoute(): React.ReactElement { const snackbar = useSnackbar(); const family = useFamily(); + const genealogy = useGenealogy(); const [filter, setFilter] = React.useState(""); @@ -37,7 +39,7 @@ export function FamilyCouplesListRoute(): React.ReactElement { return; await CoupleApi.Delete(c); - await family.reloadCouplesList(); + await genealogy.reloadCouplesList(); snackbar("La fiche du couple a été supprimée avec succès !"); } catch (e) { @@ -63,7 +65,7 @@ export function FamilyCouplesListRoute(): React.ReactElement {
- {family.couples.isEmpty ? ( + {genealogy.couples.isEmpty ? (

Votre famille n'a aucun couple enregistré pour le moment ! Utilisez le bouton situé en haut à droite pour créer le premier ! @@ -81,16 +83,16 @@ export function FamilyCouplesListRoute(): React.ReactElement { (m.wife && - family.members + genealogy.members .get(m.wife)! .fullName.toLocaleLowerCase() .includes(filter.toLocaleLowerCase())) || (m.husband && - family.members + genealogy.members .get(m.husband)! .fullName.toLocaleLowerCase() .includes(filter.toLocaleLowerCase())) === true @@ -109,14 +111,18 @@ function CouplesTable(p: { onDelete: (m: Couple) => void; }): React.ReactElement { const family = useFamily(); + const genealogy = useGenealogy(); + const n = useNavigate(); const compareInvertedMembersNames = ( v1: number | undefined, v2: number | undefined ) => { - const n1 = ((v1 && family.members.get(v1)?.invertedFullName) ?? "") || ""; - const n2 = ((v2 && family.members.get(v2)?.invertedFullName) ?? "") || ""; + const n1 = + ((v1 && genealogy.members.get(v1)?.invertedFullName) ?? "") || ""; + const n2 = + ((v2 && genealogy.members.get(v2)?.invertedFullName) ?? "") || ""; return n1?.localeCompare(n2, undefined, { ignorePunctuation: true, @@ -259,10 +265,10 @@ function CouplesTable(p: { } function MemberCell(p: { id?: number }): React.ReactElement { - const family = useFamily(); + const genealogy = useGenealogy(); if (!p.id) return <>; - const member = family.members.get(p.id!)!; + const member = genealogy.members.get(p.id!)!; return ( diff --git a/geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx index 6d02ee6..5a5fa01 100644 --- a/geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMemberRoute.tsx @@ -1,3 +1,5 @@ +import { mdiFamilyTree } from "@mdi/js"; +import Icon from "@mdi/react"; import ClearIcon from "@mui/icons-material/Clear"; import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; @@ -14,12 +16,14 @@ import { import * as EmailValidator from "email-validator"; import React from "react"; import { useNavigate, useParams } from "react-router-dom"; +import { ServerApi } from "../../../api/ServerApi"; import { Couple } from "../../../api/genealogy/CoupleApi"; import { Member, MemberApi, fmtDate } from "../../../api/genealogy/MemberApi"; -import { ServerApi } from "../../../api/ServerApi"; import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; import { useSnackbar } from "../../../hooks/context_providers/SnackbarProvider"; +import { useQuery } from "../../../hooks/useQuery"; import { AsyncWidget } from "../../../widgets/AsyncWidget"; import { useFamily } from "../../../widgets/BaseFamilyRoute"; import { ConfirmLeaveWithoutSaveDialog } from "../../../widgets/ConfirmLeaveWithoutSaveDialog"; @@ -36,10 +40,7 @@ import { PropEdit } from "../../../widgets/forms/PropEdit"; import { PropSelect } from "../../../widgets/forms/PropSelect"; import { SexSelection } from "../../../widgets/forms/SexSelection"; import { UploadPhotoButton } from "../../../widgets/forms/UploadPhotoButton"; -import { useQuery } from "../../../hooks/useQuery"; -import { mdiFamilyTree } from "@mdi/js"; -import Icon from "@mdi/react"; -import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; +import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute"; /** * Create a new member route @@ -50,6 +51,7 @@ export function FamilyCreateMemberRoute(): React.ReactElement { const [shouldQuit, setShouldQuit] = React.useState(false); const n = useNavigate(); + const genealogy = useGenealogy(); const family = useFamily(); const parameters = useQuery(); @@ -60,7 +62,7 @@ export function FamilyCreateMemberRoute(): React.ReactElement { try { const r = await MemberApi.Create(m); - await family.reloadMembersList(); + await genealogy.reloadMembersList(); setShouldQuit(true); n(family.family.URL(`genealogy/member/${r.id}`)); @@ -104,6 +106,7 @@ export function FamilyMemberRoute(): React.ReactElement { const snackbar = useSnackbar(); const family = useFamily(); + const genealogy = useGenealogy(); const { memberId } = useParams(); const [member, setMember] = React.useState(); @@ -115,7 +118,7 @@ export function FamilyMemberRoute(): React.ReactElement { count.current += 1; setMember(undefined); - await family.reloadMembersList(); + await genealogy.reloadMembersList(); }; const deleteMember = async () => { @@ -132,7 +135,7 @@ export function FamilyMemberRoute(): React.ReactElement { snackbar("La fiche de membre a été supprimée avec succès !"); n(family.family.URL("genealogy/members")); - await family.reloadMembersList(); + await genealogy.reloadMembersList(); } catch (e) { console.error(e); alert("Échec de la suppression du membre !"); @@ -148,9 +151,9 @@ export function FamilyMemberRoute(): React.ReactElement { build={() => ( n(family.family.familyTreeURL(member!))} @@ -176,6 +179,7 @@ export function FamilyEditMemberRoute(): React.ReactElement { const [shouldQuit, setShouldQuit] = React.useState(false); const family = useFamily(); + const genealogy = useGenealogy(); const [member, setMember] = React.useState(); const load = async () => { @@ -194,7 +198,7 @@ export function FamilyEditMemberRoute(): React.ReactElement { snackbar("Les informations du membre ont été mises à jour avec succès !"); - await family.reloadMembersList(); + await genealogy.reloadMembersList(); setShouldQuit(true); n(family.family.memberURL(member!)); @@ -741,6 +745,7 @@ function CoupleItem(p: { const n = useNavigate(); const family = useFamily(); + const genealogy = useGenealogy(); const statusStr = ServerApi.Config.couples_states.find( (c) => c.code === p.couple.state @@ -758,7 +763,7 @@ function CoupleItem(p: { const otherSpouseID = p.couple.wife === p.currMemberId ? p.couple.husband : p.couple.wife; const otherSpouse = otherSpouseID - ? family.members.get(otherSpouseID) + ? genealogy.members.get(otherSpouseID) : undefined; return ( diff --git a/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx index ac3be15..7996a83 100644 --- a/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMemberTreeRoute.tsx @@ -26,6 +26,7 @@ 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 { @@ -41,22 +42,23 @@ enum TreeMode { 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 = family.members.get(Number(memberId)); + 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, family.members, family.couples) - : buildDescendingTree(member.id, family.members, family.couples); + ? buildAscendingTree(member.id, genealogy.members, genealogy.couples) + : buildDescendingTree(member.id, genealogy.members, genealogy.couples); return [tree, treeHeight(tree)]; - }, [member, currMode, family.members, family.couples]); + }, [member, currMode, genealogy.members, genealogy.couples]); const [currDepth, setCurrDepth] = React.useState(0); diff --git a/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx index 425ddb4..234729d 100644 --- a/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx @@ -21,12 +21,14 @@ import { useFamily } from "../../../widgets/BaseFamilyRoute"; import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; import { MemberPhoto } from "../../../widgets/MemberPhoto"; import { RouterLink } from "../../../widgets/RouterLink"; +import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute"; export function FamilyMembersListRoute(): React.ReactElement { const alert = useAlert(); const confirm = useConfirm(); const snackbar = useSnackbar(); + const genealogy = useGenealogy(); const family = useFamily(); const [filter, setFilter] = React.useState(""); @@ -41,7 +43,7 @@ export function FamilyMembersListRoute(): React.ReactElement { return; await MemberApi.Delete(m); - await family.reloadMembersList(); + await genealogy.reloadMembersList(); snackbar("La fiche du membre a été supprimée avec succès !"); } catch (e) { @@ -67,7 +69,7 @@ export function FamilyMembersListRoute(): React.ReactElement {

- {family.members.isEmpty ? ( + {genealogy.members.isEmpty ? (

Votre famille n'a aucun membre pour le moment ! Utilisez le bouton situé en haut à droite pour créer le premier ! @@ -85,8 +87,8 @@ export function FamilyMembersListRoute(): React.ReactElement { + ? genealogy.members.fullList + : genealogy.members.filter((m) => m.fullName.toLowerCase().includes(filter.toLowerCase()) ) } @@ -102,6 +104,7 @@ function MembersTable(p: { members: Member[]; onDelete: (m: Member) => void; }): React.ReactElement { + const genealogy = useGenealogy(); const family = useFamily(); const n = useNavigate(); @@ -178,7 +181,7 @@ function MembersTable(p: { renderCell(params) { if (!params.row.father) return Non renseigné; - return family.members.get(params.row.father)!.fullName; + return genealogy.members.get(params.row.father)!.fullName; }, }, { @@ -188,7 +191,7 @@ function MembersTable(p: { renderCell(params) { if (!params.row.mother) return Non renseignée; - return family.members.get(params.row.mother)!.fullName; + return genealogy.members.get(params.row.mother)!.fullName; }, }, { diff --git a/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx b/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx index 37461af..128ee7d 100644 --- a/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/GenealogyHomeRoute.tsx @@ -1,8 +1,8 @@ -import { useFamily } from "../../../widgets/BaseFamilyRoute"; import { FamilyPageTitle } from "../../../widgets/FamilyPageTitle"; +import { useGenealogy } from "../../../widgets/genealogy/BaseGenealogyRoute"; export function GenealogyHomeRoute(): React.ReactElement { - const family = useFamily(); + const genealogy = useGenealogy(); return ( <> @@ -12,8 +12,8 @@ export function GenealogyHomeRoute(): React.ReactElement { compléter l'abre généalogique de votre famille.

 

-

Nombre de fiches de membres: {family.members.size}

-

Nombre de fiches de couples: {family.couples.size}

+

Nombre de fiches de membres: {genealogy.members.size}

+

Nombre de fiches de couples: {genealogy.couples.size}

); diff --git a/geneit_app/src/widgets/BaseFamilyRoute.tsx b/geneit_app/src/widgets/BaseFamilyRoute.tsx index ca02be9..d6f10c0 100644 --- a/geneit_app/src/widgets/BaseFamilyRoute.tsx +++ b/geneit_app/src/widgets/BaseFamilyRoute.tsx @@ -27,8 +27,6 @@ import { import React from "react"; import { Outlet, useLocation, useParams } from "react-router-dom"; import { ExtendedFamilyInfo, FamilyApi } from "../api/FamilyApi"; -import { CoupleApi, CouplesList } from "../api/genealogy/CoupleApi"; -import { MemberApi, MembersList } from "../api/genealogy/MemberApi"; import { useAlert } from "../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider"; import { useSnackbar } from "../hooks/context_providers/SnackbarProvider"; @@ -37,12 +35,8 @@ import { RouterLink } from "./RouterLink"; interface FamilyContext { family: ExtendedFamilyInfo; - members: MembersList; - couples: CouplesList; familyId: number; reloadFamilyInfo: () => void; - reloadMembersList: () => Promise; - reloadCouplesList: () => Promise; } const FamilyContextK = React.createContext(null); @@ -54,8 +48,6 @@ export function BaseFamilyRoute(): React.ReactElement { const confirm = useConfirm(); const [family, setFamily] = React.useState(null); - const [members, setMembers] = React.useState(null); - const [couples, setCouples] = React.useState(null); const loadKey = React.useRef(1); @@ -64,15 +56,11 @@ export function BaseFamilyRoute(): React.ReactElement { const load = async () => { const familyID = Number(familyId); setFamily(await FamilyApi.GetSingle(familyID)); - setMembers(await MemberApi.GetEntireList(familyID)); - setCouples(await CoupleApi.GetEntireList(familyID)); }; const onReload = async () => { loadKey.current += 1; setFamily(null); - setMembers(null); - setCouples(null); return new Promise((res, _rej) => { loadPromise.current = () => res(); @@ -106,7 +94,7 @@ export function BaseFamilyRoute(): React.ReactElement { return ( {p.label} @@ -55,7 +57,7 @@ export function MemberInput(p: { return ( { p.onValueChange(newValue?.id); }} diff --git a/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx b/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx index f2b1b3c..247663c 100644 --- a/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx +++ b/geneit_app/src/widgets/genealogy/BaseGenealogyRoute.tsx @@ -41,7 +41,7 @@ export function BaseGenealogyRoute(): React.ReactElement { return ( Date: Thu, 16 May 2024 20:39:37 +0200 Subject: [PATCH 13/15] Separate genealogy settings from family settings --- geneit_app/src/App.tsx | 2 + geneit_app/src/api/FamilyApi.ts | 6 +- .../src/routes/family/FamilySettingsRoute.tsx | 141 +---------- .../genealogy/GenalogySettingsRoute.tsx | 221 ++++++++++++++++++ geneit_app/src/widgets/BaseFamilyRoute.tsx | 9 + .../src/controllers/families_controller.rs | 31 ++- 6 files changed, 257 insertions(+), 153 deletions(-) create mode 100644 geneit_app/src/routes/family/genealogy/GenalogySettingsRoute.tsx diff --git a/geneit_app/src/App.tsx b/geneit_app/src/App.tsx index 1bb55f3..a07dcd1 100644 --- a/geneit_app/src/App.tsx +++ b/geneit_app/src/App.tsx @@ -38,6 +38,7 @@ import { FamilyTreeRoute } from "./routes/family/genealogy/FamilyTreeRoute"; import { FamilyMemberTreeRoute } from "./routes/family/genealogy/FamilyMemberTreeRoute"; import { GenealogyHomeRoute } from "./routes/family/genealogy/GenealogyHomeRoute"; import { BaseGenealogyRoute } from "./widgets/genealogy/BaseGenealogyRoute"; +import { GenalogySettingsRoute } from "./routes/family/genealogy/GenalogySettingsRoute"; interface AuthContext { signedIn: boolean; @@ -105,6 +106,7 @@ export function App(): React.ReactElement { path="tree/:memberId" element={} /> + } /> } /> diff --git a/geneit_app/src/api/FamilyApi.ts b/geneit_app/src/api/FamilyApi.ts index 763dc7e..31d97b6 100644 --- a/geneit_app/src/api/FamilyApi.ts +++ b/geneit_app/src/api/FamilyApi.ts @@ -233,9 +233,9 @@ export class FamilyApi { */ static async UpdateFamily(settings: { id: number; - name: string; - enable_genealogy: boolean; - disable_couple_photos: boolean; + name?: string; + enable_genealogy?: boolean; + disable_couple_photos?: boolean; }): Promise { await APIClient.exec({ method: "PATCH", diff --git a/geneit_app/src/routes/family/FamilySettingsRoute.tsx b/geneit_app/src/routes/family/FamilySettingsRoute.tsx index bfc4186..7c0d720 100644 --- a/geneit_app/src/routes/family/FamilySettingsRoute.tsx +++ b/geneit_app/src/routes/family/FamilySettingsRoute.tsx @@ -1,26 +1,19 @@ -import DownloadIcon from "@mui/icons-material/Download"; -import UploadIcon from "@mui/icons-material/Upload"; import { - Alert, Box, Button, CardActions, CardContent, - Checkbox, FormControlLabel, + Switch, TextField, - Tooltip, Typography, } from "@mui/material"; import React from "react"; import { useNavigate } from "react-router-dom"; import { FamilyApi } from "../../api/FamilyApi"; import { ServerApi } from "../../api/ServerApi"; -import { DataApi } from "../../api/genealogy/DataApi"; import { useAlert } from "../../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider"; -import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider"; -import { downloadBlob, selectFileToUpload } from "../../utils/files_utils"; import { useFamily } from "../../widgets/BaseFamilyRoute"; import { FamilyCard } from "../../widgets/FamilyCard"; import { formatDate } from "../../widgets/TimeWidget"; @@ -55,7 +48,6 @@ export function FamilySettingsRoute(): React.ReactElement { return ( <> - {family.family.enable_genealogy && }
- - - - - ); -} diff --git a/geneit_app/src/routes/family/genealogy/GenalogySettingsRoute.tsx b/geneit_app/src/routes/family/genealogy/GenalogySettingsRoute.tsx new file mode 100644 index 0000000..086ffca --- /dev/null +++ b/geneit_app/src/routes/family/genealogy/GenalogySettingsRoute.tsx @@ -0,0 +1,221 @@ +import DownloadIcon from "@mui/icons-material/Download"; +import UploadIcon from "@mui/icons-material/Upload"; +import { + Alert, + Box, + Button, + CardActions, + CardContent, + FormControlLabel, + Switch, + Tooltip, + Typography, +} from "@mui/material"; +import React from "react"; +import { FamilyApi } from "../../../api/FamilyApi"; +import { DataApi } from "../../../api/genealogy/DataApi"; +import { useAlert } from "../../../hooks/context_providers/AlertDialogProvider"; +import { useConfirm } from "../../../hooks/context_providers/ConfirmDialogProvider"; +import { useLoadingMessage } from "../../../hooks/context_providers/LoadingMessageProvider"; +import { downloadBlob, selectFileToUpload } from "../../../utils/files_utils"; +import { useFamily } from "../../../widgets/BaseFamilyRoute"; +import { FamilyCard } from "../../../widgets/FamilyCard"; + +export function GenalogySettingsRoute(): React.ReactElement { + return ( + <> + + + + ); +} + +function GenealogySettingsCard(): React.ReactElement { + const alert = useAlert(); + + const family = useFamily(); + + const [disableCouplePhotos, setDisableCouplePhotos] = React.useState( + family.family.disable_couple_photos + ); + + const canEdit = family.family.is_admin; + + const [error, setError] = React.useState(); + const [success, setSuccess] = React.useState(); + + const updateFamily = async () => { + try { + setError(undefined); + setSuccess(undefined); + + await FamilyApi.UpdateFamily({ + id: family.family.family_id, + disable_couple_photos: disableCouplePhotos, + }); + + family.reloadFamilyInfo(); + + alert("Les paramètres de la famille ont été mis à jour avec succès !"); + } catch (e) { + console.error(e); + setError("Echec de la mise à jour des paramètres de la famille !"); + } + }; + + return ( + + + + Paramètres du module de généalogie + + + + + setDisableCouplePhotos(c)} + /> + } + label="Désactiver les photos de couple" + /> + + + + + + + + ); +} + +function GenealogyExportCard(): React.ReactElement { + const loading = useLoadingMessage(); + const confirm = useConfirm(); + const alert = useAlert(); + + const family = useFamily(); + + const [error, setError] = React.useState(); + const [success, setSuccess] = React.useState(); + + const exportData = async () => { + loading.show("Export des données"); + try { + setError(undefined); + setSuccess(undefined); + + const blob = await DataApi.ExportData(family.familyId); + downloadBlob(blob, `Export-${new Date().getTime()}.zip`); + + setSuccess("Export des données effectué avec succès !"); + } catch (e) { + console.error(e); + setError("Echec de l'export des données de la famille !"); + } + loading.hide(); + }; + + const importData = async () => { + try { + if ( + !(await confirm( + "Attention ! Cette opération a pour effet d'effacer toutes les données existantes en base ! Voulez-vous vraiment poursuivre l'opération ?" + )) + ) + return; + + const file = await selectFileToUpload({ + allowedTypes: ["application/zip"], + }); + if (file === null) return; + + setError(undefined); + setSuccess(undefined); + + loading.show( + "Restauration des données de généalogie de la famille en cours..." + ); + + await DataApi.ImportData(family.familyId, file); + + family.reloadFamilyInfo(); + + alert( + "Import des données de généalogie de la famille effectué avec succès !" + ); + } catch (e) { + console.error(e); + setError( + `Echec de l'import des données de généalogie de la famille ! (${e})` + ); + } + + loading.hide(); + }; + + return ( + + + + Export / import des données de généalogie + +

+ Vous pouvez, à des fins de sauvegardes ou de transfert, exporter et + importer l'ensemble des données des membres et des couples de cette + famille, sous format ZIP. +

+ + + Attention ! La restauration des données de généalogie de la famille + provoque préalablement l'effacement de toutes les données enregistrées + dans la famille ! Par ailleurs, la restauration n'est pas réversible ! + + +

 

+ + + + +
+
+ ); +} diff --git a/geneit_app/src/widgets/BaseFamilyRoute.tsx b/geneit_app/src/widgets/BaseFamilyRoute.tsx index d6f10c0..2df2f58 100644 --- a/geneit_app/src/widgets/BaseFamilyRoute.tsx +++ b/geneit_app/src/widgets/BaseFamilyRoute.tsx @@ -4,6 +4,7 @@ import { mdiContentCopy, mdiCrowd, mdiFamilyTree, + mdiFileTree, mdiHumanMaleFemale, mdiLockCheck, mdiPlus, @@ -190,6 +191,14 @@ export function BaseFamilyRoute(): React.ReactElement { uri="settings" /> + {family?.enable_genealogy && ( + } + label="Généalogie" + uri="genealogy/settings" + /> + )} + {/* Invitation code */} HttpResult { #[derive(serde::Deserialize)] pub struct UpdateFamilyBody { - name: String, - enable_genealogy: bool, - disable_couple_photos: bool, + name: Option, + enable_genealogy: Option, + disable_couple_photos: Option, } /// Update a family @@ -113,17 +113,24 @@ pub async fn update( f: FamilyInPathWithAdminMembership, req: web::Json, ) -> HttpResult { - if !StaticConstraints::default() - .family_name_len - .validate(&req.name) - { - return Ok(HttpResponse::BadRequest().body("Invalid family name!")); + let mut family = families_service::get_by_id(f.family_id()).await?; + + if let Some(name) = &req.name { + if !StaticConstraints::default().family_name_len.validate(name) { + return Ok(HttpResponse::BadRequest().body("Invalid family name!")); + } + + family.name = name.to_string(); + } + + if let Some(enable_genealogy) = req.enable_genealogy { + family.enable_genealogy = enable_genealogy; + } + + if let Some(disable_couple_photos) = req.disable_couple_photos { + family.disable_couple_photos = disable_couple_photos; } - let mut family = families_service::get_by_id(f.family_id()).await?; - family.name = req.0.name; - family.enable_genealogy = req.0.enable_genealogy; - family.disable_couple_photos = req.0.disable_couple_photos; families_service::update_family(&family).await?; log::info!("User {:?} updated family {:?}", f.user_id(), f.family_id()); -- 2.45.2 From a69f0401810d852ca0b7ae0c3fe7a78d8bc3b3f3 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Thu, 16 May 2024 21:01:53 +0200 Subject: [PATCH 14/15] Update menu when disabling some features --- geneit_app/src/widgets/BaseFamilyRoute.tsx | 88 ++++++++++++---------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/geneit_app/src/widgets/BaseFamilyRoute.tsx b/geneit_app/src/widgets/BaseFamilyRoute.tsx index 2df2f58..38e6830 100644 --- a/geneit_app/src/widgets/BaseFamilyRoute.tsx +++ b/geneit_app/src/widgets/BaseFamilyRoute.tsx @@ -132,49 +132,57 @@ export function BaseFamilyRoute(): React.ReactElement { } label="Accueil" uri="" /> - - Généalogie + {family?.enable_genealogy && ( + <> + + Généalogie - } - label="Accueil" - uri="genealogy" - /> - } - label="Membres" - uri="genealogy/members" - secondaryAction={ - - - - - - - - } - /> + } + label="Accueil" + uri="genealogy" + /> + } + label="Membres" + uri="genealogy/members" + secondaryAction={ + + + + + + + + } + /> - } - label="Couples" - uri="genealogy/couples" - secondaryAction={ - - - - - - - - } - /> + } + label="Couples" + uri="genealogy/couples" + secondaryAction={ + + + + + + + + } + /> - } - label="Arbre" - uri="genealogy/tree" - /> + } + label="Arbre" + uri="genealogy/tree" + /> + + )} Administration -- 2.45.2 From bfd15a0be9a99d1ce09cc20281bfe60d4885ce6f Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Thu, 16 May 2024 21:07:26 +0200 Subject: [PATCH 15/15] Fix vertical alignment --- .../family/genealogy/FamilyMembersListRoute.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx b/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx index 234729d..9313746 100644 --- a/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx +++ b/geneit_app/src/routes/family/genealogy/FamilyMembersListRoute.tsx @@ -180,7 +180,11 @@ function MembersTable(p: { flex: 5, renderCell(params) { if (!params.row.father) - return Non renseigné; + return ( + + Non renseigné + + ); return genealogy.members.get(params.row.father)!.fullName; }, }, @@ -190,7 +194,11 @@ function MembersTable(p: { flex: 5, renderCell(params) { if (!params.row.mother) - return Non renseignée; + return ( + + Non renseignée + + ); return genealogy.members.get(params.row.mother)!.fullName; }, }, -- 2.45.2