Compare commits
4 Commits
renovate/l
...
d2a4bfb8e8
| Author | SHA1 | Date | |
|---|---|---|---|
| d2a4bfb8e8 | |||
| 88e40fece6 | |||
| c6b518d8de | |||
| cd7462ffb1 |
@@ -1,6 +1,6 @@
|
|||||||
import { APIClient } from "./ApiClient";
|
import { APIClient } from "./ApiClient";
|
||||||
import { Couple } from "./CoupleApi";
|
import { Couple } from "./CoupleApi";
|
||||||
import { Member } from "./MemberApi";
|
import { Member } from "./genealogy/MemberApi";
|
||||||
|
|
||||||
interface FamilyAPI {
|
interface FamilyAPI {
|
||||||
user_id: number;
|
user_id: number;
|
||||||
@@ -85,9 +85,11 @@ export class Family implements FamilyAPI {
|
|||||||
|
|
||||||
export class ExtendedFamilyInfo extends Family {
|
export class ExtendedFamilyInfo extends Family {
|
||||||
public disable_couple_photos: boolean;
|
public disable_couple_photos: boolean;
|
||||||
|
public enable_genealogy: boolean;
|
||||||
constructor(p: any) {
|
constructor(p: any) {
|
||||||
super(p);
|
super(p);
|
||||||
this.disable_couple_photos = p.disable_couple_photos;
|
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: {
|
static async UpdateFamily(settings: {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
enable_genealogy: boolean;
|
||||||
disable_couple_photos: boolean;
|
disable_couple_photos: boolean;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
@@ -237,6 +240,7 @@ export class FamilyApi {
|
|||||||
uri: `/family/${settings.id}`,
|
uri: `/family/${settings.id}`,
|
||||||
jsonData: {
|
jsonData: {
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
enable_genealogy: settings.enable_genealogy,
|
||||||
disable_couple_photos: settings.disable_couple_photos,
|
disable_couple_photos: settings.disable_couple_photos,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { APIClient } from "./ApiClient";
|
import { APIClient } from "../ApiClient";
|
||||||
import { DateValue, Member } from "./MemberApi";
|
import { DateValue, Member } from "./MemberApi";
|
||||||
import { ServerApi } from "./ServerApi";
|
import { ServerApi } from "../ServerApi";
|
||||||
|
|
||||||
interface CoupleApiInterface {
|
interface CoupleApiInterface {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -161,7 +161,7 @@ export class CoupleApi {
|
|||||||
*/
|
*/
|
||||||
static async Create(m: Couple): Promise<Couple> {
|
static async Create(m: Couple): Promise<Couple> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/couple/create`,
|
uri: `/family/${m.family_id}/genealogy/couple/create`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
jsonData: m,
|
jsonData: m,
|
||||||
});
|
});
|
||||||
@@ -177,7 +177,7 @@ export class CoupleApi {
|
|||||||
couple_id: number
|
couple_id: number
|
||||||
): Promise<Couple> {
|
): Promise<Couple> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${family_id}/couple/${couple_id}`,
|
uri: `/family/${family_id}/genealogy/couple/${couple_id}`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ export class CoupleApi {
|
|||||||
*/
|
*/
|
||||||
static async GetEntireList(family_id: number): Promise<CouplesList> {
|
static async GetEntireList(family_id: number): Promise<CouplesList> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${family_id}/couples`,
|
uri: `/family/${family_id}/genealogy/couples`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ export class CoupleApi {
|
|||||||
*/
|
*/
|
||||||
static async Update(m: Couple): Promise<void> {
|
static async Update(m: Couple): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/couple/${m.id}`,
|
uri: `/family/${m.family_id}/genealogy/couple/${m.id}`,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
jsonData: m,
|
jsonData: m,
|
||||||
});
|
});
|
||||||
@@ -214,7 +214,7 @@ export class CoupleApi {
|
|||||||
const fd = new FormData();
|
const fd = new FormData();
|
||||||
fd.append("photo", b);
|
fd.append("photo", b);
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/couple/${m.id}/photo`,
|
uri: `/family/${m.family_id}/genealogy/couple/${m.id}/photo`,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
formData: fd,
|
formData: fd,
|
||||||
});
|
});
|
||||||
@@ -225,7 +225,7 @@ export class CoupleApi {
|
|||||||
*/
|
*/
|
||||||
static async RemoveCouplePhoto(m: Couple): Promise<void> {
|
static async RemoveCouplePhoto(m: Couple): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/couple/${m.id}/photo`,
|
uri: `/family/${m.family_id}/genealogy/couple/${m.id}/photo`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ export class CoupleApi {
|
|||||||
*/
|
*/
|
||||||
static async Delete(m: Couple): Promise<void> {
|
static async Delete(m: Couple): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/couple/${m.id}`,
|
uri: `/family/${m.family_id}/genealogy/couple/${m.id}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { APIClient } from "./ApiClient";
|
import { APIClient } from "../ApiClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data management api client
|
* Data management api client
|
||||||
@@ -9,7 +9,7 @@ export class DataApi {
|
|||||||
*/
|
*/
|
||||||
static async ExportData(family_id: number): Promise<Blob> {
|
static async ExportData(family_id: number): Promise<Blob> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${family_id}/data/export`,
|
uri: `/family/${family_id}/genealogy/data/export`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -22,7 +22,7 @@ export class DataApi {
|
|||||||
const fd = new FormData();
|
const fd = new FormData();
|
||||||
fd.append("archive", archive);
|
fd.append("archive", archive);
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${family_id}/data/import`,
|
uri: `/family/${family_id}/genealogy/data/import`,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
formData: fd,
|
formData: fd,
|
||||||
});
|
});
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { APIClient } from "./ApiClient";
|
import { APIClient } from "../ApiClient";
|
||||||
import { Couple } from "./CoupleApi";
|
import { Couple } from "./CoupleApi";
|
||||||
|
|
||||||
export type Sex = "M" | "F";
|
export type Sex = "M" | "F";
|
||||||
@@ -278,7 +278,7 @@ export class MemberApi {
|
|||||||
*/
|
*/
|
||||||
static async Create(m: Member): Promise<Member> {
|
static async Create(m: Member): Promise<Member> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/member/create`,
|
uri: `/family/${m.family_id}/genealogy/member/create`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
jsonData: m,
|
jsonData: m,
|
||||||
});
|
});
|
||||||
@@ -294,7 +294,7 @@ export class MemberApi {
|
|||||||
member_id: number
|
member_id: number
|
||||||
): Promise<Member> {
|
): Promise<Member> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${family_id}/member/${member_id}`,
|
uri: `/family/${family_id}/genealogy/member/${member_id}`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ export class MemberApi {
|
|||||||
*/
|
*/
|
||||||
static async GetEntireList(family_id: number): Promise<MembersList> {
|
static async GetEntireList(family_id: number): Promise<MembersList> {
|
||||||
const res = await APIClient.exec({
|
const res = await APIClient.exec({
|
||||||
uri: `/family/${family_id}/members`,
|
uri: `/family/${family_id}/genealogy/members`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ export class MemberApi {
|
|||||||
*/
|
*/
|
||||||
static async Update(m: Member): Promise<void> {
|
static async Update(m: Member): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/member/${m.id}`,
|
uri: `/family/${m.family_id}/genealogy/member/${m.id}`,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
jsonData: m,
|
jsonData: m,
|
||||||
});
|
});
|
||||||
@@ -331,7 +331,7 @@ export class MemberApi {
|
|||||||
const fd = new FormData();
|
const fd = new FormData();
|
||||||
fd.append("photo", b);
|
fd.append("photo", b);
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/member/${m.id}/photo`,
|
uri: `/family/${m.family_id}/genealogy/member/${m.id}/photo`,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
formData: fd,
|
formData: fd,
|
||||||
});
|
});
|
||||||
@@ -342,7 +342,7 @@ export class MemberApi {
|
|||||||
*/
|
*/
|
||||||
static async RemoveMemberPhoto(m: Member): Promise<void> {
|
static async RemoveMemberPhoto(m: Member): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/member/${m.id}/photo`,
|
uri: `/family/${m.family_id}/genealogy/member/${m.id}/photo`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -352,7 +352,7 @@ export class MemberApi {
|
|||||||
*/
|
*/
|
||||||
static async Delete(m: Member): Promise<void> {
|
static async Delete(m: Member): Promise<void> {
|
||||||
await APIClient.exec({
|
await APIClient.exec({
|
||||||
uri: `/family/${m.family_id}/member/${m.id}`,
|
uri: `/family/${m.family_id}/genealogy/member/${m.id}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,8 @@ import SaveIcon from "@mui/icons-material/Save";
|
|||||||
import { Button, Grid, Stack } from "@mui/material";
|
import { Button, Grid, Stack } from "@mui/material";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { Couple, CoupleApi } from "../../api/CoupleApi";
|
import { Couple, CoupleApi } from "../../api/genealogy/CoupleApi";
|
||||||
import { Member } from "../../api/MemberApi";
|
import { Member } from "../../api/genealogy/MemberApi";
|
||||||
import { ServerApi } from "../../api/ServerApi";
|
import { ServerApi } from "../../api/ServerApi";
|
||||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
||||||
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { Button, TextField, Tooltip } from "@mui/material";
|
|||||||
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
|
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { Couple, CoupleApi } from "../../api/CoupleApi";
|
import { Couple, CoupleApi } from "../../api/genealogy/CoupleApi";
|
||||||
import { dateTimestamp, fmtDate } from "../../api/MemberApi";
|
import { dateTimestamp, fmtDate } from "../../api/genealogy/MemberApi";
|
||||||
import { ServerApi } from "../../api/ServerApi";
|
import { ServerApi } from "../../api/ServerApi";
|
||||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
||||||
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
||||||
@@ -132,7 +132,13 @@ function CouplesTable(p: {
|
|||||||
sortable: false,
|
sortable: false,
|
||||||
width: 60,
|
width: 60,
|
||||||
renderCell(params) {
|
renderCell(params) {
|
||||||
return <CouplePhoto couple={params.row} />;
|
return (
|
||||||
|
<div
|
||||||
|
style={{ display: "flex", alignItems: "center", height: "100%" }}
|
||||||
|
>
|
||||||
|
<CouplePhoto couple={params.row} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import {
|
|||||||
import * as EmailValidator from "email-validator";
|
import * as EmailValidator from "email-validator";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { Couple } from "../../api/CoupleApi";
|
import { Couple } from "../../api/genealogy/CoupleApi";
|
||||||
import { Member, MemberApi, fmtDate } from "../../api/MemberApi";
|
import { Member, MemberApi, fmtDate } from "../../api/genealogy/MemberApi";
|
||||||
import { ServerApi } from "../../api/ServerApi";
|
import { ServerApi } from "../../api/ServerApi";
|
||||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
||||||
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import { Button, TextField, Tooltip, Typography } from "@mui/material";
|
|||||||
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
|
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
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 { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
||||||
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
|
||||||
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
|
import { useSnackbar } from "../../hooks/context_providers/SnackbarProvider";
|
||||||
@@ -108,7 +113,13 @@ function MembersTable(p: {
|
|||||||
sortable: false,
|
sortable: false,
|
||||||
width: 60,
|
width: 60,
|
||||||
renderCell(params) {
|
renderCell(params) {
|
||||||
return <MemberPhoto member={params.row} />;
|
return (
|
||||||
|
<div
|
||||||
|
style={{ display: "flex", alignItems: "center", height: "100%" }}
|
||||||
|
>
|
||||||
|
<MemberPhoto member={params.row} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { DataApi } from "../../api/DataApi";
|
import { DataApi } from "../../api/genealogy/DataApi";
|
||||||
import { FamilyApi } from "../../api/FamilyApi";
|
import { FamilyApi } from "../../api/FamilyApi";
|
||||||
import { ServerApi } from "../../api/ServerApi";
|
import { ServerApi } from "../../api/ServerApi";
|
||||||
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
|
||||||
@@ -76,6 +76,9 @@ function FamilySettingsCard(): React.ReactElement {
|
|||||||
const family = useFamily();
|
const family = useFamily();
|
||||||
|
|
||||||
const [newName, setNewName] = React.useState(family.family.name);
|
const [newName, setNewName] = React.useState(family.family.name);
|
||||||
|
const [enableGenealogy, setEnableGenealogy] = React.useState(
|
||||||
|
family.family.enable_genealogy
|
||||||
|
);
|
||||||
const [disableCouplePhotos, setDisableCouplePhotos] = React.useState(
|
const [disableCouplePhotos, setDisableCouplePhotos] = React.useState(
|
||||||
family.family.disable_couple_photos
|
family.family.disable_couple_photos
|
||||||
);
|
);
|
||||||
@@ -93,6 +96,7 @@ function FamilySettingsCard(): React.ReactElement {
|
|||||||
await FamilyApi.UpdateFamily({
|
await FamilyApi.UpdateFamily({
|
||||||
id: family.family.family_id,
|
id: family.family.family_id,
|
||||||
name: newName,
|
name: newName,
|
||||||
|
enable_genealogy: enableGenealogy,
|
||||||
disable_couple_photos: disableCouplePhotos,
|
disable_couple_photos: disableCouplePhotos,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -144,18 +148,34 @@ function FamilySettingsCard(): React.ReactElement {
|
|||||||
maxLength: ServerApi.Config.constraints.family_name_len.max,
|
maxLength: ServerApi.Config.constraints.family_name_len.max,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tooltip title="Les photos de couple ne sont pas utilisées en pratique dans les arbres généalogiques. Il est possible de masquer les formulaires d'édition de photos de couple pour limiter le risque de confusion.">
|
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={disableCouplePhotos}
|
checked={enableGenealogy}
|
||||||
onChange={(_e, c) => setDisableCouplePhotos(c)}
|
onChange={(_e, c) => setEnableGenealogy(c)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Désactiver les photos de couple"
|
label="Activer la généalogie"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
{enableGenealogy && (
|
||||||
|
<Tooltip
|
||||||
|
title="Les photos de couple ne sont pas utilisées en pratique dans les arbres généalogiques. Il est possible de masquer les formulaires d'édition de photos de couple pour limiter le risque de confusion."
|
||||||
|
arrow
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
disabled={!canEdit}
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={disableCouplePhotos}
|
||||||
|
onChange={(_e, c) => setDisableCouplePhotos(c)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Désactiver les photos de couple"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardActions>
|
<CardActions>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Couple, CouplesList } from "../api/CoupleApi";
|
import { Couple, CouplesList } from "../api/genealogy/CoupleApi";
|
||||||
import { Member, MembersList, dateTimestamp } from "../api/MemberApi";
|
import { Member, MembersList, dateTimestamp } from "../api/genealogy/MemberApi";
|
||||||
|
|
||||||
export interface CoupleInformation {
|
export interface CoupleInformation {
|
||||||
couple: Couple;
|
couple: Couple;
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ import {
|
|||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Outlet, useLocation, useParams } from "react-router-dom";
|
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 { 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 { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
||||||
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
|
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
|
||||||
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
|
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
|||||||
import { TreeItem, SimpleTreeView } from "@mui/x-tree-view";
|
import { TreeItem, SimpleTreeView } from "@mui/x-tree-view";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { Couple } from "../api/CoupleApi";
|
import { Couple } from "../api/genealogy/CoupleApi";
|
||||||
import { Member, fmtDate } from "../api/MemberApi";
|
import { Member, fmtDate } from "../api/genealogy/MemberApi";
|
||||||
import { FamilyTreeNode } from "../utils/family_tree";
|
import { FamilyTreeNode } from "../utils/family_tree";
|
||||||
import { useFamily } from "./BaseFamilyRoute";
|
import { useFamily } from "./BaseFamilyRoute";
|
||||||
import { MemberPhoto } from "./MemberPhoto";
|
import { MemberPhoto } from "./MemberPhoto";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Avatar } from "@mui/material";
|
import { Avatar } from "@mui/material";
|
||||||
import { Couple } from "../api/CoupleApi";
|
import { Couple } from "../api/genealogy/CoupleApi";
|
||||||
|
|
||||||
export function CouplePhoto(p: {
|
export function CouplePhoto(p: {
|
||||||
couple: Couple;
|
couple: Couple;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
ListItemSecondaryAction,
|
ListItemSecondaryAction,
|
||||||
ListItemText,
|
ListItemText,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Member, fmtDate } from "../api/MemberApi";
|
import { Member, fmtDate } from "../api/genealogy/MemberApi";
|
||||||
import { MemberPhoto } from "./MemberPhoto";
|
import { MemberPhoto } from "./MemberPhoto";
|
||||||
import Icon from "@mdi/react";
|
import Icon from "@mdi/react";
|
||||||
import FemaleIcon from "@mui/icons-material/Female";
|
import FemaleIcon from "@mui/icons-material/Female";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Avatar } from "@mui/material";
|
import { Avatar } from "@mui/material";
|
||||||
import { Member } from "../api/MemberApi";
|
import { Member } from "../api/genealogy/MemberApi";
|
||||||
|
|
||||||
export function MemberPhoto(p: {
|
export function MemberPhoto(p: {
|
||||||
member?: Member;
|
member?: Member;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Stack, TextField, Typography } from "@mui/material";
|
import { Stack, TextField, Typography } from "@mui/material";
|
||||||
import { NumberConstraint, ServerApi } from "../../api/ServerApi";
|
import { NumberConstraint, ServerApi } from "../../api/ServerApi";
|
||||||
import { DateValue, fmtDate } from "../../api/MemberApi";
|
import { DateValue, fmtDate } from "../../api/genealogy/MemberApi";
|
||||||
import { PropEdit } from "./PropEdit";
|
import { PropEdit } from "./PropEdit";
|
||||||
|
|
||||||
export function DateInput(p: {
|
export function DateInput(p: {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import ClearIcon from "@mui/icons-material/Clear";
|
|||||||
import { Autocomplete, IconButton, TextField, Typography } from "@mui/material";
|
import { Autocomplete, IconButton, TextField, Typography } from "@mui/material";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { Member } from "../../api/MemberApi";
|
import { Member } from "../../api/genealogy/MemberApi";
|
||||||
import { useFamily } from "../BaseFamilyRoute";
|
import { useFamily } from "../BaseFamilyRoute";
|
||||||
import { MemberItem } from "../MemberItem";
|
import { MemberItem } from "../MemberItem";
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
Radio,
|
Radio,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Sex } from "../../api/MemberApi";
|
import { Sex } from "../../api/genealogy/MemberApi";
|
||||||
|
|
||||||
export function SexSelection(p: {
|
export function SexSelection(p: {
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { IconButton, Tooltip } from "@mui/material";
|
|||||||
import jsPDF from "jspdf";
|
import jsPDF from "jspdf";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
||||||
import { Couple } from "../../api/CoupleApi";
|
import { Couple } from "../../api/genealogy/CoupleApi";
|
||||||
import { Member } from "../../api/MemberApi";
|
import { Member } from "../../api/genealogy/MemberApi";
|
||||||
import { useDarkTheme } from "../../hooks/context_providers/DarkThemeProvider";
|
import { useDarkTheme } from "../../hooks/context_providers/DarkThemeProvider";
|
||||||
import { FamilyTreeNode } from "../../utils/family_tree";
|
import { FamilyTreeNode } from "../../utils/family_tree";
|
||||||
import { downloadBlob } from "../../utils/files_utils";
|
import { downloadBlob } from "../../utils/files_utils";
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- Remove column to toggle genealogy
|
||||||
|
ALTER TABLE public.families
|
||||||
|
DROP COLUMN enable_genealogy;
|
||||||
@@ -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';
|
||||||
@@ -79,6 +79,7 @@ pub async fn list(token: LoginToken) -> HttpResult {
|
|||||||
struct RichFamilyInfo {
|
struct RichFamilyInfo {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
membership: FamilyMembership,
|
membership: FamilyMembership,
|
||||||
|
enable_genealogy: bool,
|
||||||
disable_couple_photos: 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?;
|
let family = families_service::get_by_id(f.family_id()).await?;
|
||||||
Ok(HttpResponse::Ok().json(RichFamilyInfo {
|
Ok(HttpResponse::Ok().json(RichFamilyInfo {
|
||||||
membership,
|
membership,
|
||||||
|
enable_genealogy: family.enable_genealogy,
|
||||||
disable_couple_photos: family.disable_couple_photos,
|
disable_couple_photos: family.disable_couple_photos,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -102,6 +104,7 @@ pub async fn leave(f: FamilyInPath) -> HttpResult {
|
|||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct UpdateFamilyBody {
|
pub struct UpdateFamilyBody {
|
||||||
name: String,
|
name: String,
|
||||||
|
enable_genealogy: bool,
|
||||||
disable_couple_photos: 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?;
|
let mut family = families_service::get_by_id(f.family_id()).await?;
|
||||||
family.name = req.0.name;
|
family.name = req.0.name;
|
||||||
|
family.enable_genealogy = req.0.enable_genealogy;
|
||||||
family.disable_couple_photos = req.0.disable_couple_photos;
|
family.disable_couple_photos = req.0.disable_couple_photos;
|
||||||
families_service::update_family(&family).await?;
|
families_service::update_family(&family).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -137,71 +137,71 @@ async fn main() -> std::io::Result<()> {
|
|||||||
"/family/{id}/user/{user_id}",
|
"/family/{id}/user/{user_id}",
|
||||||
web::delete().to(families_controller::delete_membership),
|
web::delete().to(families_controller::delete_membership),
|
||||||
)
|
)
|
||||||
// Members controller
|
// [GENEALOGY] Members controller
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/member/create",
|
"/family/{id}/genealogy/member/create",
|
||||||
web::post().to(members_controller::create),
|
web::post().to(members_controller::create),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/members",
|
"/family/{id}/genealogy/members",
|
||||||
web::get().to(members_controller::get_all),
|
web::get().to(members_controller::get_all),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/member/{member_id}",
|
"/family/{id}/genealogy/member/{member_id}",
|
||||||
web::get().to(members_controller::get_single),
|
web::get().to(members_controller::get_single),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/member/{member_id}",
|
"/family/{id}/genealogy/member/{member_id}",
|
||||||
web::put().to(members_controller::update),
|
web::put().to(members_controller::update),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/member/{member_id}",
|
"/family/{id}/genealogy/member/{member_id}",
|
||||||
web::delete().to(members_controller::delete),
|
web::delete().to(members_controller::delete),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/member/{member_id}/photo",
|
"/family/{id}/genealogy/member/{member_id}/photo",
|
||||||
web::put().to(members_controller::set_photo),
|
web::put().to(members_controller::set_photo),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/member/{member_id}/photo",
|
"/family/{id}/genealogy/member/{member_id}/photo",
|
||||||
web::delete().to(members_controller::remove_photo),
|
web::delete().to(members_controller::remove_photo),
|
||||||
)
|
)
|
||||||
// Couples controller
|
// [GENEALOGY] Couples controller
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couple/create",
|
"/family/{id}/genealogy/couple/create",
|
||||||
web::post().to(couples_controller::create),
|
web::post().to(couples_controller::create),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couples",
|
"/family/{id}/genealogy/couples",
|
||||||
web::get().to(couples_controller::get_all),
|
web::get().to(couples_controller::get_all),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couple/{couple_id}",
|
"/family/{id}/genealogy/couple/{couple_id}",
|
||||||
web::get().to(couples_controller::get_single),
|
web::get().to(couples_controller::get_single),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couple/{couple_id}",
|
"/family/{id}/genealogy/couple/{couple_id}",
|
||||||
web::put().to(couples_controller::update),
|
web::put().to(couples_controller::update),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couple/{couple_id}",
|
"/family/{id}/genealogy/couple/{couple_id}",
|
||||||
web::delete().to(couples_controller::delete),
|
web::delete().to(couples_controller::delete),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couple/{couple_id}/photo",
|
"/family/{id}/genealogy/couple/{couple_id}/photo",
|
||||||
web::put().to(couples_controller::set_photo),
|
web::put().to(couples_controller::set_photo),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/couple/{couple_id}/photo",
|
"/family/{id}/genealogy/couple/{couple_id}/photo",
|
||||||
web::delete().to(couples_controller::remove_photo),
|
web::delete().to(couples_controller::remove_photo),
|
||||||
)
|
)
|
||||||
// Data controller
|
// [GENEALOGY] Data controller
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/data/export",
|
"/family/{id}/genealogy/data/export",
|
||||||
web::get().to(data_controller::export_family),
|
web::get().to(data_controller::export_family),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/data/import",
|
"/family/{id}/genealogy/data/import",
|
||||||
web::put().to(data_controller::import_family),
|
web::put().to(data_controller::import_family),
|
||||||
)
|
)
|
||||||
// Photos controller
|
// Photos controller
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ pub struct Family {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub invitation_code: String,
|
pub invitation_code: String,
|
||||||
pub disable_couple_photos: bool,
|
pub disable_couple_photos: bool,
|
||||||
|
pub enable_genealogy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Family {
|
impl Family {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ diesel::table! {
|
|||||||
#[max_length = 7]
|
#[max_length = 7]
|
||||||
invitation_code -> Varchar,
|
invitation_code -> Varchar,
|
||||||
disable_couple_photos -> Bool,
|
disable_couple_photos -> Bool,
|
||||||
|
enable_genealogy -> Bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ pub async fn update_family(family: &Family) -> anyhow::Result<()> {
|
|||||||
.set((
|
.set((
|
||||||
families::dsl::name.eq(family.name.clone()),
|
families::dsl::name.eq(family.name.clone()),
|
||||||
families::dsl::invitation_code.eq(family.invitation_code.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),
|
families::dsl::disable_couple_photos.eq(family.disable_couple_photos),
|
||||||
))
|
))
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
|
|||||||
Reference in New Issue
Block a user