414 Commits

Author SHA1 Message Date
7e5c065001 fix: eslint issues
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2026-04-02 21:03:43 +02:00
30486b3847 fix: auto-resolvable eslint issues 2026-04-02 20:38:43 +02:00
3813b89119 feat: make the front and the back bundled in a single binary
Some checks failed
continuous-integration/drone/push Build is failing
2026-04-02 20:36:42 +02:00
16c9dadc64 fix: build issues
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-02 19:15:43 +02:00
5c453dc093 chore: improve dev docker compose
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-02 19:05:22 +02:00
e018a8b172 chore: update backend dependencies 2026-04-02 18:37:37 +02:00
fb3f95bdab chore: update frontend dependencies 2026-04-02 18:14:15 +02:00
ec2b687107 Merge pull request 'Update Rust crate sha2 to 0.11.0' (#757) from renovate/sha2-0.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2026-04-02 00:25:02 +00:00
232bfe2fcb Update Rust crate sha2 to 0.11.0
Some checks failed
continuous-integration/drone/push Build is failing
renovate/stability-days Updates have met minimum release age requirement
continuous-integration/drone/pr Build is failing
2026-04-01 00:25:55 +00:00
7ce56d42af Merge pull request 'Update Rust crate lettre to 0.11.20' (#756) from renovate/lettre-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-04-01 00:25:14 +00:00
427c0f1726 Update Rust crate lettre to 0.11.20
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-31 00:25:53 +00:00
442799b78a Merge pull request 'Update Rust crate env_logger to 0.11.10' (#755) from renovate/env_logger-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-31 00:25:16 +00:00
d6171b7275 Update Rust crate env_logger to 0.11.10
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-30 00:26:52 +00:00
1c910027a5 Merge pull request 'Update dependency filesize to ^11.0.15' (#754) from renovate/filesize-11.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-30 00:25:35 +00:00
5c8f27ccf6 Update dependency filesize to ^11.0.15
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-29 00:26:27 +00:00
c5803a6434 Merge pull request 'Update Rust crate tempfile to 3.27.0' (#753) from renovate/tempfile-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-29 00:26:18 +00:00
421aad28d1 Update Rust crate tempfile to 3.27.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-28 00:24:13 +00:00
a49838e056 Merge pull request 'Update dependency @mui/x-data-grid to ^8.28.1' (#752) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-28 00:23:34 +00:00
9c1d5bdf45 Update dependency @mui/x-data-grid to ^8.28.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-27 00:25:18 +00:00
ac83dbfbc7 Merge pull request 'Update dependency react-easy-crop to ^5.5.7' (#751) from renovate/react-easy-crop-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-27 00:25:11 +00:00
4f9a01c42b Update dependency react-easy-crop to ^5.5.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-25 00:21:33 +00:00
4ef9d79c58 Merge pull request 'Update dependency react-router-dom to ^7.13.2' (#750) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-25 00:21:28 +00:00
234486ec88 Update dependency react-router-dom to ^7.13.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-24 00:34:02 +00:00
6d8948b264 Merge pull request 'Update Rust crate serde_with to 3.18.0' (#749) from renovate/serde_with-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-24 00:33:57 +00:00
31eb1bbdda Update Rust crate serde_with to 3.18.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-23 00:33:15 +00:00
a023144b9b Merge pull request 'Update Rust crate rust-s3 to 0.37.1' (#748) from renovate/rust-s3-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-23 00:32:08 +00:00
f4d1ad1872 Update Rust crate rust-s3 to 0.37.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-22 00:33:49 +00:00
2cdef6f122 Merge pull request 'Update dependency @mui/x-data-grid to ^8.28.0' (#747) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-22 00:33:38 +00:00
aa8145183b Update dependency @mui/x-data-grid to ^8.28.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-21 00:25:52 +00:00
3ecae1d9cf Merge pull request 'Update Rust crate lazy-regex to 3.6.0' (#746) from renovate/lazy-regex-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-21 00:25:44 +00:00
615e590133 Update Rust crate lazy-regex to 3.6.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-20 00:26:25 +00:00
7162bb905f Merge pull request 'Update Rust crate clap to 4.6.0' (#745) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-20 00:26:14 +00:00
7e4855f679 Update Rust crate clap to 4.6.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-18 00:27:31 +00:00
07e4451a08 Merge pull request 'Update dependency typescript-eslint to ^8.57.1' (#744) from renovate/typescript-eslint into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-18 00:26:55 +00:00
9b68ca23b4 Update dependency typescript-eslint to ^8.57.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-17 00:26:25 +00:00
556ad797a6 Merge pull request 'Update Rust crate bcrypt to 0.19.0' (#743) from renovate/bcrypt-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-17 00:26:15 +00:00
ee3e7d9e34 Update Rust crate bcrypt to 0.19.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-16 00:28:58 +00:00
57d36a9dbf Merge pull request 'Update dependency typescript-eslint to ^8.57.0' (#742) from renovate/typescript-eslint into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-16 00:27:41 +00:00
d89725a68c Update dependency typescript-eslint to ^8.57.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-15 00:28:38 +00:00
6ba898c97b Merge pull request 'Update Rust crate diesel to 2.3.7' (#741) from renovate/diesel-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-15 00:28:13 +00:00
21b957a4ba Update Rust crate diesel to 2.3.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-14 00:28:57 +00:00
ca1ffb1141 Merge pull request 'Update dependency dayjs to ^1.11.20' (#740) from renovate/dayjs-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-14 00:28:39 +00:00
c398a28428 Update dependency dayjs to ^1.11.20
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-13 00:27:10 +00:00
35cfd0527f Merge pull request 'Update dependency @mui/x-data-grid to ^8.27.5' (#739) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-13 00:27:03 +00:00
5ee599ece8 Update dependency @mui/x-data-grid to ^8.27.5
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-12 00:28:33 +00:00
217c2f65d9 Merge pull request 'Update Rust crate image to 0.25.10' (#738) from renovate/image-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-12 00:27:58 +00:00
b8e831f23b Update Rust crate image to 0.25.10
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-11 00:17:04 +00:00
b12477baa9 Merge pull request 'Update Rust crate mailchecker to 6.0.20' (#737) from renovate/mailchecker-6.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-11 00:16:47 +00:00
6e20fc16ed Update Rust crate mailchecker to 6.0.20
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-10 00:15:54 +00:00
0e49b11c46 Merge pull request 'Update materialui to ^7.3.9' (#736) from renovate/materialui into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-10 00:15:24 +00:00
29e2f69277 Update materialui to ^7.3.9
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-09 00:15:15 +00:00
872d60775c Merge pull request 'Update dependency eslint to ^9.39.4' (#735) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-09 00:15:02 +00:00
31464c2cd4 Update dependency eslint to ^9.39.4
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-08 00:15:24 +00:00
12110235ea Merge pull request 'Update dependency @eslint/js to ^9.39.4' (#734) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-08 00:15:19 +00:00
4d320eb685 Update dependency @eslint/js to ^9.39.4
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-07 00:19:20 +00:00
9e066e70f0 Merge pull request 'Update dependency @mui/x-data-grid to ^8.27.4' (#733) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-07 00:19:07 +00:00
98df27fce9 Update dependency @mui/x-data-grid to ^8.27.4
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-06 00:16:08 +00:00
cc70998524 Merge pull request 'Update Rust crate actix-web to 4.13.0' (#732) from renovate/actix-web-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-06 00:16:02 +00:00
1db98f2ef5 Update Rust crate actix-web to 4.13.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-05 00:15:27 +00:00
ebde19e56a Merge pull request 'Update dependency typescript-eslint to ^8.56.1' (#731) from renovate/typescript-eslint into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-05 00:14:57 +00:00
47e1b35db7 Update dependency typescript-eslint to ^8.56.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-04 00:19:22 +00:00
6f3144d994 Merge pull request 'Update Rust crate chrono to 0.4.44' (#730) from renovate/chrono-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-04 00:19:07 +00:00
f9100e953e Update Rust crate chrono to 0.4.44
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-03 00:19:20 +00:00
e1d4ad4f5a Merge pull request 'Update Rust crate anyhow to 1.0.102' (#729) from renovate/anyhow-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-03 00:19:11 +00:00
870e74ad2d Update Rust crate anyhow to 1.0.102
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-02 00:20:27 +00:00
8dfb54fe84 Merge pull request 'Update dependency react-router-dom to ^7.13.1' (#728) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-02 00:20:16 +00:00
179c3d747a Update dependency react-router-dom to ^7.13.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-01 00:19:52 +00:00
8cd9fa2d69 Merge pull request 'Update dependency eslint-plugin-react-refresh to ^0.5.2' (#727) from renovate/eslint-plugin-react-refresh-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-01 00:19:46 +00:00
752dd8ab17 Update dependency eslint-plugin-react-refresh to ^0.5.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-28 00:14:42 +00:00
070d536993 Merge pull request 'Update dependency eslint to ^9.39.3' (#726) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-28 00:14:33 +00:00
a5f74932de Update dependency eslint to ^9.39.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-27 00:13:21 +00:00
23a9e7e509 Merge pull request 'Update dependency @mui/x-data-grid to ^8.27.3' (#725) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-27 00:13:16 +00:00
a9a4eb0fe4 Update dependency @mui/x-data-grid to ^8.27.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-26 00:14:01 +00:00
078668834a Merge pull request 'Update dependency @mui/x-tree-view to ^8.27.2' (#724) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-26 00:13:56 +00:00
8c11fc2b96 Update dependency @mui/x-tree-view to ^8.27.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-24 00:13:52 +00:00
038975dbf2 Merge pull request 'Update dependency @fontsource/roboto to ^5.2.10' (#723) from renovate/fontsource-roboto-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-24 00:13:44 +00:00
0e2d91d6b1 Update dependency @fontsource/roboto to ^5.2.10
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-23 00:14:29 +00:00
10d268fd2a Merge pull request 'Update dependency @mui/x-date-pickers to ^8.27.2' (#722) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-23 00:14:23 +00:00
89261ca6ea Update dependency @mui/x-date-pickers to ^8.27.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-22 00:14:35 +00:00
69e4e85667 Merge pull request 'Update dependency @eslint/js to ^9.39.3' (#721) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-22 00:14:21 +00:00
564997aa10 Update dependency @eslint/js to ^9.39.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-21 00:14:37 +00:00
50cd0d8351 Merge pull request 'Update Rust crate clap to 4.5.60' (#720) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-21 00:14:30 +00:00
21d8ee31ad Update Rust crate clap to 4.5.60
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-20 00:14:28 +00:00
b76dcb2c96 Merge pull request 'Update Rust crate futures-util to 0.3.32' (#719) from renovate/futures-util-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-20 00:14:18 +00:00
fe7ccf57b3 Update Rust crate futures-util to 0.3.32
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-19 00:16:20 +00:00
f404cf5462 Merge pull request 'Update Rust crate env_logger to 0.11.9' (#718) from renovate/env_logger-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-19 00:16:02 +00:00
e5d07a48b6 Update Rust crate env_logger to 0.11.9
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-18 00:26:23 +00:00
204615e294 Merge pull request 'Update Rust crate clap to 4.5.59' (#717) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-18 00:26:09 +00:00
299e2aa238 Update Rust crate clap to 4.5.59
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-17 00:26:47 +00:00
f59a361797 Merge pull request 'Update materialui to ^7.3.8' (#716) from renovate/materialui into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-17 00:26:35 +00:00
af99297a0e Update materialui to ^7.3.8
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-16 00:26:49 +00:00
d740e10b24 Merge pull request 'Update dependency @mui/x-tree-view to ^8.27.1' (#715) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-16 00:26:29 +00:00
ba254a1083 Update dependency @mui/x-tree-view to ^8.27.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-15 00:26:47 +00:00
00da4c66bc Merge pull request 'Update dependency @mui/x-data-grid to ^8.27.1' (#714) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-15 00:26:38 +00:00
a998fcc259 Update dependency @mui/x-data-grid to ^8.27.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-14 00:26:22 +00:00
9420690100 Merge pull request 'Update dependency @types/react to ^19.2.14' (#713) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-14 00:26:15 +00:00
f7b3aab857 Update dependency @types/react to ^19.2.14
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-13 00:26:32 +00:00
e86406f373 Merge pull request 'Update dependency @mui/x-tree-view to ^8.27.0' (#712) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-13 00:26:23 +00:00
59bfd890c6 Update dependency @mui/x-tree-view to ^8.27.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-10 00:26:09 +00:00
c3114f86e9 Merge pull request 'Update Rust crate rand to 0.10.0' (#711) from renovate/rand-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-09 00:26:13 +00:00
1a82027ba1 Update Rust crate rand to 0.10.0
Some checks failed
renovate/artifacts Artifact file update failure
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2026-02-09 00:26:10 +00:00
bb10281ddf Merge pull request 'Update dependency @mui/x-date-pickers to ^8.27.0' (#710) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-09 00:25:55 +00:00
7c87ba271d Update dependency @mui/x-date-pickers to ^8.27.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-08 00:26:09 +00:00
981eb347a9 Merge pull request 'Update Rust crate anyhow to 1.0.101' (#709) from renovate/anyhow-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-08 00:25:52 +00:00
cd42ed5744 Update Rust crate anyhow to 1.0.101
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-07 00:26:02 +00:00
27fdb328dd Merge pull request 'Update dependency @types/react to ^19.2.13' (#708) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-07 00:25:50 +00:00
d336059794 Update dependency @types/react to ^19.2.13
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-06 00:26:00 +00:00
eda5504226 Merge pull request 'Update Rust crate light-openid to 1.1.0' (#707) from renovate/light-openid-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-06 00:25:54 +00:00
bff605507c Update Rust crate light-openid to 1.1.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-05 00:26:10 +00:00
c556b32cb2 Merge pull request 'Update Rust crate clap to 4.5.57' (#706) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-05 00:25:56 +00:00
2f36136f3e Update Rust crate clap to 4.5.57
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-04 00:25:53 +00:00
29c95984ac Merge pull request 'Update dependency @mui/x-data-grid to ^8.27.0' (#705) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-04 00:25:44 +00:00
6c815c8cc0 Update dependency @mui/x-data-grid to ^8.27.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-03 00:25:47 +00:00
b0a6c3082c Merge pull request 'Update dependency eslint-plugin-react-refresh to ^0.5.0' (#704) from renovate/eslint-plugin-react-refresh-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-03 00:25:38 +00:00
a7d987d54b Update dependency eslint-plugin-react-refresh to ^0.5.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-02 00:25:47 +00:00
2297340e38 Merge pull request 'Update Rust crate lazy-regex to 3.5.1' (#703) from renovate/lazy-regex-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-02 00:25:38 +00:00
2435ea905e Update Rust crate lazy-regex to 3.5.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-02-01 00:25:33 +00:00
9cbefc0c71 Merge pull request 'Update dependency typescript-eslint to ^8.54.0' (#702) from renovate/typescript-eslint into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-01 00:24:27 +00:00
d40dee7d46 Update dependency typescript-eslint to ^8.54.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-31 00:24:44 +00:00
a855d4be4d Merge pull request 'Update Rust crate clap to 4.5.56' (#701) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-31 00:24:37 +00:00
a2dab677d3 Update Rust crate clap to 4.5.56
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-30 00:26:09 +00:00
5660397227 Merge pull request 'Update Rust crate diesel_migrations to 2.3.1' (#700) from renovate/diesel_migrations-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-30 00:26:02 +00:00
d6ea48ca0e Update Rust crate diesel_migrations to 2.3.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-29 00:26:06 +00:00
9dd3b7b176 Merge pull request 'Update react' (#699) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-29 00:25:50 +00:00
9124dd8e2f Update react
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-28 00:25:59 +00:00
62a990f8df Merge pull request 'Update Rust crate diesel to 2.3.6' (#698) from renovate/diesel-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-28 00:25:53 +00:00
8a9f40cb9b Update Rust crate diesel to 2.3.6
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-27 00:25:27 +00:00
eb847d2c27 Merge pull request 'Update dependency react-router-dom to ^7.13.0' (#697) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-27 00:25:16 +00:00
d273127dea Update dependency react-router-dom to ^7.13.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-26 00:25:48 +00:00
27a87b6e2a Merge pull request 'Update dependency @mui/x-tree-view to ^8.26.0' (#696) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-26 00:25:37 +00:00
c6e0d38f7b Update dependency @mui/x-tree-view to ^8.26.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-25 00:26:18 +00:00
1ec9c26b5b Merge pull request 'Update dependency @mui/x-date-pickers to ^8.26.0' (#695) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-25 00:26:09 +00:00
016015a2ab Update dependency @mui/x-date-pickers to ^8.26.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-24 00:25:05 +00:00
5ab90ba64a Merge pull request 'Update dependency @mui/x-data-grid to ^8.26.0' (#694) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-24 00:24:54 +00:00
1d0196d7e3 Update dependency @mui/x-data-grid to ^8.26.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-23 00:25:05 +00:00
dd67318cb9 Merge pull request 'Update Rust crate bcrypt to 0.18.0' (#693) from renovate/bcrypt-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-23 00:24:54 +00:00
6bab5c1963 Update Rust crate bcrypt to 0.18.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-22 00:26:34 +00:00
c4d224d8d2 Merge pull request 'Update dependency @types/react to ^19.2.9' (#692) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-22 00:26:21 +00:00
b2403f61d4 Update dependency @types/react to ^19.2.9
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-21 00:13:04 +00:00
86d1da2288 Merge pull request 'Update dependency typescript-eslint to ^8.53.1' (#691) from renovate/typescript-eslint into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-21 00:12:32 +00:00
e30f0ac0df Update dependency typescript-eslint to ^8.53.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-20 00:10:28 +00:00
efecbb025c Merge pull request 'Update Rust crate thiserror to 2.0.18' (#690) from renovate/thiserror-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-20 00:10:22 +00:00
182e622a16 Update Rust crate thiserror to 2.0.18
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-19 00:10:14 +00:00
728c6e5ee3 Merge pull request 'Update dependency @mui/x-tree-view to ^8.25.0' (#689) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-19 00:10:05 +00:00
0b89c20d76 Update dependency @mui/x-tree-view to ^8.25.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-18 00:10:19 +00:00
84e41a97d0 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.25.0' (#688) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-18 00:10:04 +00:00
4b7943429f Update dependency @mui/x-date-pickers to ^8.25.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-17 00:10:14 +00:00
0f31150bb6 Merge pull request 'Update dependency @mui/x-data-grid to ^8.25.0' (#687) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-17 00:09:59 +00:00
3fb085bba5 Update dependency @mui/x-data-grid to ^8.25.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-16 00:24:53 +00:00
2c837f6f84 Merge pull request 'Update Rust crate chrono to 0.4.43' (#686) from renovate/chrono-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-16 00:24:45 +00:00
ab7a795b63 Update Rust crate chrono to 0.4.43
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-15 00:29:52 +00:00
073e5660eb Merge pull request 'Update dependency react-router-dom to ^7.12.0' (#685) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-15 00:29:32 +00:00
441c33f0ec Update dependency react-router-dom to ^7.12.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-14 00:28:35 +00:00
2aeacc151e Merge pull request 'Update dependency @mui/x-tree-view to ^8.24.0' (#684) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-14 00:28:27 +00:00
9bb4d280b6 Update dependency @mui/x-tree-view to ^8.24.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-13 00:24:39 +00:00
0fff368b03 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.24.0' (#683) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-13 00:24:33 +00:00
1440e04ce9 Update dependency @mui/x-date-pickers to ^8.24.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-12 00:25:33 +00:00
d945a5e3d6 Merge pull request 'Update dependency @types/react to ^19.2.8' (#682) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-12 00:25:25 +00:00
525e33081e Update dependency @types/react to ^19.2.8
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-11 00:24:42 +00:00
470cce2647 Merge pull request 'Update dependency @mui/x-data-grid to ^8.24.0' (#681) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-11 00:24:37 +00:00
6da9b317ea Update dependency @mui/x-data-grid to ^8.24.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-10 00:24:51 +00:00
53d3be561e Merge pull request 'Update materialui to ^7.3.7' (#680) from renovate/materialui into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-10 00:24:39 +00:00
4d0d1722c9 Update materialui to ^7.3.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-09 00:21:29 +00:00
00366435b1 Merge pull request 'Update dependency vite to ^7.3.1' (#679) from renovate/vite-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-09 00:21:22 +00:00
30240a3a7e Update dependency vite to ^7.3.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-08 00:21:34 +00:00
48d268b746 Merge pull request 'Update Rust crate serde_json to 1.0.149' (#678) from renovate/serde_json-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-08 00:21:29 +00:00
eef19c13f9 Update Rust crate serde_json to 1.0.149
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-07 00:21:20 +00:00
0743f06f66 Merge pull request 'Update dependency svg2pdf.js to ^2.7.0' (#677) from renovate/svg2pdf.js-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-07 00:21:07 +00:00
d8054295ce Update dependency svg2pdf.js to ^2.7.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-06 00:21:30 +00:00
aad4ac9f36 Merge pull request 'Update Rust crate clap to 4.5.54' (#676) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-06 00:21:25 +00:00
37dbf1cea9 Update Rust crate clap to 4.5.54
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-05 00:21:43 +00:00
8b502dd034 Merge pull request 'Update dependency vite to ^7.3.0' (#675) from renovate/vite-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-05 00:21:33 +00:00
15f274c2e1 Update dependency vite to ^7.3.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-31 00:29:21 +00:00
b3d2e444dd Merge pull request 'Update dependency typescript-eslint to ^8.51.0' (#674) from renovate/typescript-eslint into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-31 00:29:03 +00:00
13bcfa31ab Update dependency typescript-eslint to ^8.51.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-30 00:30:34 +00:00
e6d19736d5 Merge pull request 'Update dependency @mui/x-tree-view to ^8.23.0' (#673) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-30 00:30:16 +00:00
f75f08a5fb Update dependency @mui/x-tree-view to ^8.23.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-29 00:30:29 +00:00
1698556f94 Merge pull request 'Update Rust crate serde_json to 1.0.148' (#672) from renovate/serde_json-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-29 00:30:02 +00:00
899a3ceb18 Update Rust crate serde_json to 1.0.148
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-28 00:29:06 +00:00
3e414d665c Merge pull request 'Update dependency @mui/x-date-pickers to ^8.23.0' (#671) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-28 00:28:54 +00:00
f45529939f Update dependency @mui/x-date-pickers to ^8.23.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-27 00:29:22 +00:00
b6aafbe808 Merge pull request 'Update dependency @mui/x-data-grid to ^8.23.0' (#670) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-27 00:29:06 +00:00
605247363d Update dependency @mui/x-data-grid to ^8.23.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-25 00:29:45 +00:00
f78747bed8 Merge pull request 'Update Rust crate serde_json to 1.0.147' (#669) from renovate/serde_json-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-25 00:29:35 +00:00
2b5fae4555 Update Rust crate serde_json to 1.0.147
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-24 00:29:15 +00:00
7b2d59661d Merge pull request 'Update fullcalendar to ^6.1.20' (#668) from renovate/fullcalendar into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-24 00:28:59 +00:00
966512e435 Update fullcalendar to ^6.1.20
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-23 00:29:02 +00:00
81d05fb93e Merge pull request 'Update dependency react-router-dom to ^7.11.0' (#667) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-23 00:28:56 +00:00
0c54883670 Update dependency react-router-dom to ^7.11.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-22 00:30:25 +00:00
760fd5a174 Merge pull request 'Update dependency @mui/x-tree-view to ^8.22.0' (#666) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-22 00:30:16 +00:00
ac91c9ad28 Update dependency @mui/x-tree-view to ^8.22.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-21 00:29:29 +00:00
01aa8b1d26 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.22.1' (#665) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-21 00:29:13 +00:00
c9118a0bc0 Update dependency @mui/x-date-pickers to ^8.22.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-20 00:28:38 +00:00
e214fd3284 Merge pull request 'Update dependency @mui/x-data-grid to ^8.22.1' (#664) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-20 00:28:28 +00:00
8b15db76e4 Update dependency @mui/x-data-grid to ^8.22.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-19 00:28:40 +00:00
30896ddc4a Merge pull request 'Update react to ^19.2.3' (#663) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-19 00:28:28 +00:00
6be84681ef Update react to ^19.2.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-18 00:31:10 +00:00
bf24bec927 Merge pull request 'Update dependency eslint-plugin-react-refresh to ^0.4.26' (#662) from renovate/eslint-plugin-react-refresh-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-18 00:31:00 +00:00
4947ecffa3 Update dependency eslint-plugin-react-refresh to ^0.4.26
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-17 00:29:34 +00:00
04d284ad56 Merge pull request 'Update dependency eslint to ^9.39.2' (#661) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-17 00:29:29 +00:00
9939b63ce2 Update dependency eslint to ^9.39.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-16 00:29:32 +00:00
68bac96767 Merge pull request 'Update dependency @eslint/js to ^9.39.2' (#660) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-16 00:29:24 +00:00
77041702e4 Update dependency @eslint/js to ^9.39.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-13 00:29:08 +00:00
f95c7eb957 Merge pull request 'Update Rust crate actix-web to 4.12.1' (#659) from renovate/actix-web-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-12 00:29:27 +00:00
d347834694 Merge pull request 'Update dependency react-router-dom to ^7.10.1' (#658) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-12 00:29:19 +00:00
3b4997423e Update Rust crate actix-web to 4.12.1
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-12-11 00:29:58 +00:00
cf83577a7f Update dependency react-router-dom to ^7.10.1
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-12-11 00:29:53 +00:00
f4800cd348 Merge pull request 'Update dependency @mui/x-tree-view to ^8.21.0' (#657) from renovate/mui-x-tree-view-8.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-12-11 00:29:41 +00:00
3c11387900 Update dependency @mui/x-tree-view to ^8.21.0
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2025-12-10 00:30:59 +00:00
779507960c Merge pull request 'Update dependency vite to ^7.2.7' (#656) from renovate/vite-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-10 00:30:51 +00:00
23bed12df4 Update dependency vite to ^7.2.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-09 00:29:00 +00:00
248884d6fc Merge pull request 'Update dependency @mui/x-date-pickers to ^8.21.0' (#655) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-09 00:28:54 +00:00
d575c9d787 Update dependency @mui/x-date-pickers to ^8.21.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-08 00:29:13 +00:00
89b8ec59ff Merge pull request 'Update dependency @mui/x-data-grid to ^8.21.0' (#654) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-08 00:29:01 +00:00
a7a65edd6d Update dependency @mui/x-data-grid to ^8.21.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-07 00:28:55 +00:00
69ce56f6d7 Merge pull request 'Update Rust crate log to 0.4.29' (#653) from renovate/log-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-07 00:28:48 +00:00
c39c232d0e Update Rust crate log to 0.4.29
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-06 00:29:50 +00:00
285ebd0826 Merge pull request 'Update react to ^19.2.1' (#652) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-06 00:29:41 +00:00
9db3932927 Update react to ^19.2.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-05 00:14:40 +00:00
80c8369928 Merge pull request 'Update materialui to ^7.3.6' (#651) from renovate/materialui into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-05 00:14:34 +00:00
c249955aa5 Update materialui to ^7.3.6
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-04 00:14:43 +00:00
7ba187bf3f Merge pull request 'Update dependency typescript-eslint to ^8.48.1' (#650) from renovate/typescript-eslint-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-04 00:14:38 +00:00
250617ca72 Update dependency typescript-eslint to ^8.48.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-03 00:14:16 +00:00
1ed9826954 Merge pull request 'Update dependency vite to ^7.2.6' (#649) from renovate/vite-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-03 00:14:10 +00:00
99b14ea92d Update dependency vite to ^7.2.6
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-02 00:13:43 +00:00
a29c186676 Merge pull request 'Update materialui to ^7.3.5' (#648) from renovate/materialui into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-02 00:13:32 +00:00
a5ff8b6d56 Update materialui to ^7.3.5
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-01 00:12:56 +00:00
22c8cbf187 Merge pull request 'Update dependency typescript-eslint to ^8.48.0' (#647) from renovate/typescript-eslint-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-12-01 00:12:46 +00:00
25eeec2622 Update dependency typescript-eslint to ^8.48.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-30 00:13:17 +00:00
0e7ab6f2f5 Merge pull request 'Update dependency @mui/x-tree-view to ^8.19.0' (#646) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-30 00:13:06 +00:00
3c726f3c4a Update dependency @mui/x-tree-view to ^8.19.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-29 00:13:44 +00:00
ba01f18fda Merge pull request 'Update dependency react-easy-crop to ^5.5.6' (#645) from renovate/react-easy-crop-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-29 00:13:34 +00:00
dac909eeac Update dependency react-easy-crop to ^5.5.6
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-28 00:14:06 +00:00
4bdf59fd6c Merge pull request 'Update dependency @mui/x-data-grid to ^8.20.0' (#644) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-28 00:13:57 +00:00
c0e9a4304b Update dependency @mui/x-data-grid to ^8.20.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-27 00:15:14 +00:00
1483243aef Merge pull request 'Update dependency @mui/x-date-pickers to ^8.19.0' (#643) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-27 00:15:09 +00:00
d5c6f6152a Update dependency @mui/x-date-pickers to ^8.19.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-26 00:08:28 +00:00
0008626e26 Merge pull request 'Update dependency @types/react to ^19.2.7' (#642) from renovate/react into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-11-26 00:08:19 +00:00
6c5efa385d Update dependency @types/react to ^19.2.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-25 00:07:51 +00:00
33a39cec4a Merge pull request 'Update dependency @fontsource/roboto to ^5.2.9' (#641) from renovate/fontsource-roboto-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-25 00:07:44 +00:00
62b055a640 Update dependency @fontsource/roboto to ^5.2.9
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-24 00:07:46 +00:00
6c27dcf7de Merge pull request 'Update Rust crate clap to 4.5.53' (#640) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-24 00:07:37 +00:00
0b7805246d Update Rust crate clap to 4.5.53
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-23 00:10:02 +00:00
ba0ccb9cd2 Merge pull request 'Update dependency vite to ^7.2.4' (#639) from renovate/vite-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-23 00:08:48 +00:00
668f15ef99 Update dependency vite to ^7.2.4
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-22 00:08:05 +00:00
b1fe143df6 Merge pull request 'Update dependency react-easy-crop to ^5.5.5' (#638) from renovate/react-easy-crop-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-22 00:07:53 +00:00
1b27f23c91 Update dependency react-easy-crop to ^5.5.5
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-21 00:10:17 +00:00
c6fb88d874 Merge pull request 'Update dependency jspdf to ^3.0.4' (#637) from renovate/jspdf-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-21 00:10:04 +00:00
cd996cde26 Update dependency jspdf to ^3.0.4
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-20 00:08:03 +00:00
9ffd13c95d Merge pull request 'Update dependency @types/react to ^19.2.6' (#636) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-20 00:07:54 +00:00
0fd90cad2e Update dependency @types/react to ^19.2.6
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-19 00:08:19 +00:00
78884f67da Merge pull request 'Update Rust crate clap to 4.5.52' (#635) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-19 00:08:13 +00:00
2d8efd0da6 Update Rust crate clap to 4.5.52
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-18 00:09:31 +00:00
a7badf3080 Merge pull request 'Update Rust crate image to 0.25.9' (#634) from renovate/image-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-18 00:09:22 +00:00
e5b1a66e08 Update Rust crate image to 0.25.9
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-17 00:08:35 +00:00
f14a4ce26d Merge pull request 'Update react' (#633) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-17 00:08:27 +00:00
33097b574d Update react
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-16 00:09:19 +00:00
a8b5b634c7 Merge pull request 'Update dependency react-router-dom to ^7.9.6' (#632) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-16 00:09:11 +00:00
3c8f950cf6 Update dependency react-router-dom to ^7.9.6
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-15 00:08:51 +00:00
ef9406a65e Merge pull request 'Update dependency vite to ^7.2.2' (#631) from renovate/vite-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-15 00:08:36 +00:00
7971da214f Update dependency vite to ^7.2.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-13 00:08:13 +00:00
5218b9f00d Merge pull request 'Update dependency react-router-dom to ^7.9.5' (#489) from renovate/react-router-dom-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-13 00:08:07 +00:00
083d8899fe Update dependency react-router-dom to ^7.9.5
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-12 00:09:48 +00:00
c4e3be3332 Merge pull request 'Update dependency typescript-eslint to ^8.46.4' (#630) from renovate/typescript-eslint-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-12 00:09:38 +00:00
9d72861764 Update dependency typescript-eslint to ^8.46.4
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-11 00:09:25 +00:00
23717c84fd Merge pull request 'Update dependency globals to ^16.5.0' (#629) from renovate/globals-16.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-11 00:09:16 +00:00
418bc666d7 Update dependency globals to ^16.5.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-10 00:07:55 +00:00
7475db587a Merge pull request 'Update dependency eslint to ^9.39.1' (#628) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-10 00:07:44 +00:00
409cb15a9d Update dependency eslint to ^9.39.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-09 00:09:42 +00:00
177524665f Merge pull request 'Update dependency @mui/x-tree-view to ^8.17.0' (#627) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-09 00:09:32 +00:00
3f8d6e71c5 Update dependency @mui/x-tree-view to ^8.17.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-08 00:07:50 +00:00
2cd2ead069 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.17.0' (#626) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-08 00:07:45 +00:00
8a5cf6423d Update dependency @mui/x-date-pickers to ^8.17.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-07 00:10:21 +00:00
2a80a3bdec Merge pull request 'Update dependency @mui/x-data-grid to ^8.17.0' (#625) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-07 00:10:12 +00:00
dab3b1f9e5 Update dependency @mui/x-data-grid to ^8.17.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-06 00:08:07 +00:00
c94c8f58ce Merge pull request 'Update dependency @eslint/js to ^9.39.1' (#624) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-06 00:07:59 +00:00
99fafd4f42 Update dependency @eslint/js to ^9.39.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-05 00:09:02 +00:00
844f1c3589 Merge pull request 'Update dependency typescript-eslint to ^8.46.3' (#623) from renovate/typescript-eslint-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-05 00:08:55 +00:00
c3607c05c0 Update dependency typescript-eslint to ^8.46.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-04 00:11:33 +00:00
53f5fcfbcb Merge pull request 'Update dependency @mui/x-data-grid to ^8.16.0' (#622) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-04 00:11:24 +00:00
ecc11b6242 Update dependency @mui/x-data-grid to ^8.16.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-03 00:08:06 +00:00
21cc865a21 Merge pull request 'Update dependency dayjs to ^1.11.19' (#621) from renovate/dayjs-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-03 00:07:57 +00:00
2d5ce4587d Update dependency dayjs to ^1.11.19
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-02 00:08:38 +00:00
f84c4d7c76 Merge pull request 'Update Rust crate lazy-regex to 3.4.2' (#620) from renovate/lazy-regex-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-02 00:08:31 +00:00
509ceb1ed1 Update Rust crate lazy-regex to 3.4.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-11-01 00:09:38 +00:00
6a2b2ecbb1 Merge pull request 'Update dependency typescript-eslint to ^8.46.2' (#617) from renovate/typescript-eslint-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-11-01 00:09:11 +00:00
ad213f1a94 Merge pull request 'Update Rust crate clap to 4.5.51' (#619) from renovate/clap-4.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-11-01 00:08:44 +00:00
b0cfde2a73 Update dependency typescript-eslint to ^8.46.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-31 00:35:30 +00:00
37b63e1979 Update Rust crate clap to 4.5.51
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-10-31 00:35:07 +00:00
1d42f549f0 Merge pull request 'Update react' (#618) from renovate/react into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-10-30 00:37:11 +00:00
a339da2bc7 Update react
Some checks failed
renovate/artifacts Artifact file update failure
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-10-30 00:37:05 +00:00
e96ffd9bc4 Merge pull request 'Update dependency svg2pdf.js to ^2.6.0' (#616) from renovate/svg2pdf.js-2.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-10-29 00:36:14 +00:00
313072220e Update dependency svg2pdf.js to ^2.6.0
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-10-28 00:46:51 +00:00
f115517913 Merge pull request 'Update dependency typescript to ^5.9.3' (#615) from renovate/typescript-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-27 00:36:44 +00:00
bee03941a1 Update dependency typescript to ^5.9.3
Some checks failed
renovate/artifacts Artifact file update failure
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-10-27 00:36:36 +00:00
b5d9f6071e Merge pull request 'Update dependency @mui/x-tree-view to ^8.15.0' (#614) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-27 00:36:12 +00:00
6e9f396313 Update dependency @mui/x-tree-view to ^8.15.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-26 00:36:41 +00:00
361530be18 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.15.0' (#613) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-26 00:36:30 +00:00
5c842f749b Update dependency @mui/x-date-pickers to ^8.15.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-25 00:36:32 +00:00
affb13ab73 Merge pull request 'Update dependency @mui/x-data-grid to ^8.15.0' (#612) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-25 00:36:25 +00:00
acdfc11170 Update dependency @mui/x-data-grid to ^8.15.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-24 00:37:08 +00:00
406ad94ce3 Merge pull request 'Update dependency eslint to ^9.38.0' (#611) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-24 00:37:01 +00:00
82f76950a9 Update dependency eslint to ^9.38.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-23 00:36:15 +00:00
8d4bbe100e Merge pull request 'Update dependency @eslint/js to ^9.38.0' (#610) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-23 00:36:09 +00:00
c6c675eccd Update dependency @eslint/js to ^9.38.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-22 00:36:49 +00:00
c1b998f04b Merge pull request 'Update Rust crate clap to 4.5.50' (#609) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-22 00:36:43 +00:00
bb2f1a7d51 Update Rust crate clap to 4.5.50
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-21 00:37:08 +00:00
1148645f51 Merge pull request 'Update Rust crate mailchecker to 6.0.19' (#608) from renovate/mailchecker-6.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-21 00:37:01 +00:00
6de98d017c Update Rust crate mailchecker to 6.0.19
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-20 00:35:28 +00:00
816ae1ebd1 Merge pull request 'Update dependency @mui/x-tree-view to ^8.14.1' (#607) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-20 00:35:20 +00:00
f5d75c32f9 Update dependency @mui/x-tree-view to ^8.14.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-19 00:36:37 +00:00
e25de677c1 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.14.1' (#606) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-19 00:36:31 +00:00
9456773e0f Update dependency @mui/x-date-pickers to ^8.14.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-18 00:36:11 +00:00
43bc978f5d Merge pull request 'Update dependency @mui/x-data-grid to ^8.14.1' (#605) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-18 00:36:04 +00:00
c929f1a771 Update dependency @mui/x-data-grid to ^8.14.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-17 00:35:58 +00:00
521cd99c90 Merge pull request 'Update dependency eslint-plugin-react-refresh to ^0.4.24' (#604) from renovate/eslint-plugin-react-refresh-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-17 00:35:50 +00:00
7d3877b0de Update dependency eslint-plugin-react-refresh to ^0.4.24
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-16 00:36:15 +00:00
9555d535b1 Merge pull request 'Update dependency globals to ^16.4.0' (#603) from renovate/globals-16.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-16 00:36:02 +00:00
15054df5c7 Update dependency globals to ^16.4.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-15 00:34:38 +00:00
5723098ded Merge pull request 'Update Rust crate clap to 4.5.49' (#602) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-15 00:34:26 +00:00
f0d249fa5e Update Rust crate clap to 4.5.49
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-14 00:36:51 +00:00
af79f812ca Merge pull request 'Update dependency eslint to ^9.37.0' (#601) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-14 00:36:43 +00:00
c71032ec9c Update dependency eslint to ^9.37.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-13 00:37:15 +00:00
3fdf575010 Merge pull request 'Update dependency @mui/x-tree-view to ^8.14.0' (#600) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-13 00:37:08 +00:00
77f78529f6 Update dependency @mui/x-tree-view to ^8.14.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-12 00:35:37 +00:00
2f5626d5e1 Merge pull request 'Update dependency @mui/x-date-pickers to ^8.14.0' (#599) from renovate/mui-x-date-pickers-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-12 00:35:30 +00:00
ffb02dd579 Update dependency @mui/x-date-pickers to ^8.14.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-11 00:35:19 +00:00
4a1d3f5628 Merge pull request 'Update dependency @mui/x-data-grid to ^8.14.0' (#598) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-11 00:35:11 +00:00
58449a65af Update dependency @mui/x-data-grid to ^8.14.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-10 00:34:12 +00:00
11850cd581 Merge pull request 'Update Rust crate lettre to 0.11.19' (#597) from renovate/lettre-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-10 00:34:04 +00:00
82cc7dc745 Update Rust crate lettre to 0.11.19
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-09 00:11:30 +00:00
5cf11dc061 Merge pull request 'Update dependency @eslint/js to ^9.37.0' (#596) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-09 00:10:44 +00:00
4639666097 Update dependency @eslint/js to ^9.37.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-08 00:10:57 +00:00
e3fb01174a Merge pull request 'Update Rust crate thiserror to 2.0.17' (#595) from renovate/thiserror-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-08 00:10:44 +00:00
bfea5d2e81 Update Rust crate thiserror to 2.0.17
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-07 00:11:53 +00:00
85a0ba0356 Merge pull request 'Update Rust crate serde to 1.0.228' (#594) from renovate/serde-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-07 00:11:23 +00:00
a9f9ab28bd Update Rust crate serde to 1.0.228
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-06 00:13:09 +00:00
d48ef08e6d Merge pull request 'Update Rust crate redis to 0.32.7' (#593) from renovate/redis-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-06 00:13:01 +00:00
4a9a67ed21 Update Rust crate redis to 0.32.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-05 00:13:57 +00:00
467232a9c4 Merge pull request 'Update dependency react-easy-crop to ^5.5.3' (#592) from renovate/react-easy-crop-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-05 00:13:27 +00:00
c4a53b0383 Update dependency react-easy-crop to ^5.5.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-04 00:35:34 +00:00
688c25f0eb Merge pull request 'Update dependency eslint-plugin-react-refresh to ^0.4.23' (#591) from renovate/eslint-plugin-react-refresh-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-04 00:35:28 +00:00
229f3b010b Update dependency eslint-plugin-react-refresh to ^0.4.23
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-03 00:36:18 +00:00
6da6161903 Merge pull request 'Update dependency eslint to ^9.36.0' (#545) from renovate/eslint-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-03 00:36:11 +00:00
997a17f807 Update dependency eslint to ^9.36.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-02 00:36:03 +00:00
a78d217cf3 Merge pull request 'Update Rust crate clap to 4.5.48' (#590) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-02 00:35:54 +00:00
63a3cb953c Update Rust crate clap to 4.5.48
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-10-01 00:34:34 +00:00
4d29a28103 Merge pull request 'Update Rust crate anyhow to 1.0.100' (#589) from renovate/anyhow-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-10-01 00:34:23 +00:00
f45b9b0f8b Update Rust crate anyhow to 1.0.100
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-30 00:34:04 +00:00
be5d3f6015 Merge pull request 'Update dependency @types/react to ^19.1.15' (#588) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-30 00:33:55 +00:00
5b83a417dd Update dependency @types/react to ^19.1.15
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-29 00:33:57 +00:00
6d4a9f44ff Merge pull request 'Update dependency react-easy-crop to ^5.5.2' (#587) from renovate/react-easy-crop-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-29 00:33:50 +00:00
c0c3192529 Update dependency react-easy-crop to ^5.5.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-28 00:34:04 +00:00
4f3d970b70 Merge pull request 'Update dependency @types/react to ^19.1.14' (#586) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-28 00:33:58 +00:00
2f86c72786 Update dependency @types/react to ^19.1.14
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-27 00:35:40 +00:00
7d3f6dbf33 Merge pull request 'Update dependency eslint-plugin-react-refresh to ^0.4.22' (#585) from renovate/eslint-plugin-react-refresh-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-27 00:35:34 +00:00
1bd5abc322 Update dependency eslint-plugin-react-refresh to ^0.4.22
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-26 00:34:10 +00:00
bb16d06b47 Merge pull request 'Update dependency jspdf to ^3.0.3' (#584) from renovate/jspdf-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-26 00:34:03 +00:00
34ea65ab1d Update dependency jspdf to ^3.0.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-24 00:34:58 +00:00
cab6ab3701 Merge pull request 'Update dependency filesize to ^11.0.13' (#583) from renovate/filesize-11.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-24 00:34:49 +00:00
1003bdd931 Update dependency filesize to ^11.0.13
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-22 00:35:58 +00:00
36dd681c84 Merge pull request 'Update Rust crate serde_json to 1.0.145' (#582) from renovate/serde_json-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-22 00:35:42 +00:00
feffd18395 Update Rust crate serde_json to 1.0.145
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-21 00:38:04 +00:00
0a12bf917e Merge pull request 'Update dependency @mui/x-tree-view to ^8.11.3' (#581) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-21 00:37:46 +00:00
0a263cf076 Update dependency @mui/x-tree-view to ^8.11.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-20 00:34:48 +00:00
33f7b762dd Merge pull request 'Update dependency @mui/x-data-grid to ^8.11.3' (#580) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-20 00:34:40 +00:00
593f10dfd1 Update dependency @mui/x-data-grid to ^8.11.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-19 00:33:55 +00:00
62545d1689 Merge pull request 'Update dependency @fontsource/roboto to ^5.2.8' (#579) from renovate/fontsource-roboto-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-19 00:33:48 +00:00
a8951888b8 Update dependency @fontsource/roboto to ^5.2.8
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-18 00:34:45 +00:00
abaf7b163c Merge pull request 'Update Rust crate serde to 1.0.225' (#578) from renovate/serde-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-18 00:34:40 +00:00
6f683a65fb Update Rust crate serde to 1.0.225
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-17 00:34:18 +00:00
b297f2de2d Merge pull request 'Update dependency react-easy-crop to ^5.5.1' (#577) from renovate/react-easy-crop-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-17 00:34:10 +00:00
5ed6aa0567 Update dependency react-easy-crop to ^5.5.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-16 00:34:11 +00:00
3857503e2d Merge pull request 'Update dependency @fontsource/roboto to ^5.2.7' (#576) from renovate/fontsource-roboto-5.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-16 00:34:05 +00:00
41e0022c1f Update dependency @fontsource/roboto to ^5.2.7
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-15 00:34:46 +00:00
2748206ca6 Merge pull request 'Update dependency @mui/x-data-grid to ^8.11.2' (#575) from renovate/mui-x-data-grid-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-15 00:34:40 +00:00
3813949bc5 Update dependency @mui/x-data-grid to ^8.11.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-14 00:35:06 +00:00
d93f198f98 Merge pull request 'Update dependency @types/react to ^19.1.13' (#574) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-14 00:34:52 +00:00
1264e2a636 Update dependency @types/react to ^19.1.13
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-13 00:35:33 +00:00
99c7253619 Merge pull request 'Update dependency @eslint/js to ^9.35.0' (#573) from renovate/eslint-js-9.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-13 00:35:27 +00:00
167d90a4b9 Update dependency @eslint/js to ^9.35.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-12 00:34:32 +00:00
f983a22eb8 Merge pull request 'Update dependency @mui/x-tree-view to ^8.11.2' (#572) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-12 00:34:20 +00:00
ffae610848 Update dependency @mui/x-tree-view to ^8.11.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-11 00:33:36 +00:00
6989b1ab92 Merge pull request 'Update Rust crate thiserror to 2.0.16' (#571) from renovate/thiserror-2.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-11 00:33:29 +00:00
77e72635bf Update Rust crate thiserror to 2.0.16
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-10 00:34:00 +00:00
e9dca75d1e Merge pull request 'Update Rust crate chrono to 0.4.42' (#570) from renovate/chrono-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-10 00:33:30 +00:00
5893fde734 Update Rust crate chrono to 0.4.42
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-09 00:34:14 +00:00
4a51ef08a9 Merge pull request 'Update Rust crate serde_json to 1.0.143' (#569) from renovate/serde_json-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-09 00:34:06 +00:00
7f106d042a Update Rust crate serde_json to 1.0.143
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-08 00:35:14 +00:00
80396a17d0 Merge pull request 'Update Rust crate log to 0.4.28' (#568) from renovate/log-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-08 00:34:04 +00:00
04640caa5c Update Rust crate log to 0.4.28
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-07 00:35:05 +00:00
975ac224d4 Merge pull request 'Update Rust crate image to 0.25.8' (#567) from renovate/image-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-07 00:33:55 +00:00
7e4f5cee9d Update Rust crate image to 0.25.8
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-06 00:34:44 +00:00
bf0e5e9e4f Merge pull request 'Update dependency @mui/x-tree-view to ^8.11.1' (#566) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-06 00:34:35 +00:00
2b8955475d Update dependency @mui/x-tree-view to ^8.11.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-05 00:20:37 +00:00
bcfbf61c6a Merge pull request 'Update Rust crate clap to 4.5.47' (#565) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-05 00:20:29 +00:00
0506e72d31 Update Rust crate clap to 4.5.47
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-04 00:27:12 +00:00
f82f920046 Merge pull request 'Update dependency @mui/lab to ^7.0.0-beta.17' (#564) from renovate/mui-lab-7.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-04 00:27:05 +00:00
5b31e50ff6 Update dependency @mui/lab to ^7.0.0-beta.17
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-03 00:26:39 +00:00
93987e30cf Merge pull request 'Update Rust crate redis to 0.32.5' (#563) from renovate/redis-0.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-03 00:26:33 +00:00
60e4ca93c7 Update Rust crate redis to 0.32.5
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-02 00:27:05 +00:00
71cb01c7fc Merge pull request 'Update dependency jspdf to ^3.0.2' (#562) from renovate/jspdf-3.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-02 00:25:52 +00:00
7599881cfe Update dependency jspdf to ^3.0.2
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-01 00:26:02 +00:00
12f298ef56 Merge pull request 'Update dependency dayjs to ^1.11.18' (#561) from renovate/dayjs-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-01 00:25:48 +00:00
866ee01bb1 Update dependency dayjs to ^1.11.18
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-31 00:25:59 +00:00
7a585efd8a Merge pull request 'Update dependency @mui/x-tree-view to ^8.11.0' (#534) from renovate/mui-x-tree-view-8.x into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-31 00:25:54 +00:00
935ab75d5b Update dependency @mui/x-tree-view to ^8.11.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-30 00:26:28 +00:00
1d661fb4d8 Merge pull request 'Update react' (#560) from renovate/react into master
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-30 00:26:17 +00:00
849d9aba82 Update react
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-29 00:27:19 +00:00
a435d4623f Fix theme issue
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-28 08:34:56 +02:00
4e4fa37b3b Fix build issue
All checks were successful
continuous-integration/drone/push Build is passing
2025-08-28 08:31:25 +02:00
0540f515ec Fix cargo clippy issues
Some checks failed
continuous-integration/drone/push Build is failing
2025-08-28 08:15:50 +02:00
6e53486832 Merge pull request 'Update Rust crate mailchecker to 6.0.18' (#559) from renovate/mailchecker-6.x into master
Some checks failed
continuous-integration/drone/push Build is failing
2025-08-26 00:25:43 +00:00
44d09b54e8 Update Rust crate mailchecker to 6.0.18
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2025-08-25 00:26:14 +00:00
74 changed files with 3639 additions and 3643 deletions

View File

@@ -4,32 +4,69 @@ type: docker
name: default
steps:
- name: web_build
image: node:25
volumes:
- name: web_app
path: /tmp/web_build
commands:
- cd geneit_app
- npm install
- npm run lint
- npm run build
- mv dist /tmp/web_build
- name: backend_check
image: rust
volumes:
- name: rust_registry
path: /usr/local/cargo/registry
commands:
- apt update && apt install -y cmake
- rustup component add clippy
- cd geneit_backend
- cargo clippy -- -D warnings
- cargo test
- name: app_deploy
image: node:24
environment:
AWS_ACCESS_KEY_ID:
from_secret: AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
from_secret: AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION: us-east-1
- name: backend_compile
image: rust
volumes:
- name: rust_registry
path: /usr/local/cargo/registry
- name: web_app
path: /tmp/web_build
- name: release
path: /tmp/release
depends_on:
- backend_check
- web_build
commands:
# Build website
- cd geneit_app
- npm install
- GENERATE_SOURCEMAP=false npm run build
# Install AWS
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
- unzip awscliv2.zip
- ./aws/install
- aws configure set default.s3.signature_version s3v4
# Upload to bucket
- bash upload_bucket.sh
- cd geneit_backend
- mv /tmp/web_build/dist static
- cargo build --release
- cp target/release/geneit_backend /tmp/release
- name: gitea_release
image: plugins/gitea-release
depends_on:
- backend_compile
when:
event:
- tag
volumes:
- name: release
path: /tmp/release
environment:
PLUGIN_API_KEY:
from_secret: API_KEY # needs repository read & write access
settings:
base_url: https://gitea.communiquons.org
files: /tmp/release/*
checksum: sha512
volumes:
- name: rust_registry
temp: {}
- name: web_app
temp: {}
- name: release
temp: {}

15
Makefile Normal file
View File

@@ -0,0 +1,15 @@
all: app backend
app:
cd geneit_app && npm run build && cd ..
rm -rf geneit_backend/static
mv geneit_app/dist geneit_backend/static
backend: app
cd geneit_backend && cargo clippy -- -D warnings && cargo build --release
DOCKER_TEMP_DIR := $(shell mktemp -d)
backend_docker: backend
cp geneit_backend/target/release/geneit_backend $(DOCKER_TEMP_DIR)
docker build -t pierre42100/geneit_backend -f geneit_backend/Dockerfile "$(DOCKER_TEMP_DIR)"
rm -rf $(DOCKER_TEMP_DIR)

View File

@@ -10,7 +10,8 @@
2. Start services:
```bash
cd geneit_backend
docker-compose up
mkdir -p storage/{rustfs,db,redis-data,redis-conf}
docker compose up
```
@@ -22,7 +23,7 @@ cargo install diesel_cli --no-default-features --features postgres
```
4. Initialize database:
4. Initialize database manually (or it will be done automatically when the backend is started):
```bash
diesel migration run
@@ -34,19 +35,9 @@ diesel migration run
> PGPASSWORD=pass psql -h localhost -p 5432 -U user -d geneit
> ```
## Test OIDC credentials
Emails:
```
harley@qlik.example
barb@qlik.example
quinn@qlik.example
sim@qlik.example
phillie@qlik.example
peta@qlik.example
sibylla@qlik.example
evan@qlik.example
franklin@qlik.example
```
Useful links:
Password: `Password1!`
* Mailcatcher: http://localhost:1080/
* Rustfs console: http://localhost:9090 (credentials: `topsecret` / `topsecret`)
* Dex OpenID configuration: http://127.0.0.1:9001/dex/.well-known/openid-configuration

View File

@@ -1 +1 @@
VITE_APP_BACKEND=http://localhost:8000
VITE_APP_BACKEND=http://localhost:8000/api

View File

@@ -1 +1 @@
VITE_APP_BACKEND=https://geneit-backend.communiquons.org
VITE_APP_BACKEND=/api

File diff suppressed because it is too large Load Diff

View File

@@ -12,45 +12,45 @@
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@fontsource/roboto": "^5.2.6",
"@fullcalendar/core": "^6.1.19",
"@fullcalendar/daygrid": "^6.1.19",
"@fullcalendar/interaction": "^6.1.19",
"@fullcalendar/list": "^6.1.19",
"@fullcalendar/react": "^6.1.19",
"@fontsource/roboto": "^5.2.10",
"@fullcalendar/core": "^6.1.20",
"@fullcalendar/daygrid": "^6.1.20",
"@fullcalendar/interaction": "^6.1.20",
"@fullcalendar/list": "^6.1.20",
"@fullcalendar/react": "^6.1.20",
"@mdi/js": "^7.4.47",
"@mdi/react": "^1.6.1",
"@mui/icons-material": "^7.2.0",
"@mui/lab": "^7.0.0-beta.16",
"@mui/material": "^7.2.0",
"@mui/x-data-grid": "^8.9.2",
"@mui/x-date-pickers": "^8.9.2",
"@mui/x-tree-view": "^8.8.0",
"date-and-time": "^3.6.0",
"dayjs": "^1.11.13",
"@mui/icons-material": "^7.3.9",
"@mui/lab": "^7.0.1-beta.23",
"@mui/material": "^7.3.9",
"@mui/x-data-grid": "^8.28.2",
"@mui/x-date-pickers": "^8.27.2",
"@mui/x-tree-view": "^8.27.2",
"date-and-time": "^4.4.0",
"dayjs": "^1.11.20",
"email-validator": "^2.0.4",
"filesize": "^11.0.2",
"jspdf": "^3.0.1",
"mui-color-input": "^7.0.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-easy-crop": "^5.5.0",
"filesize": "^11.0.15",
"jspdf": "^4.2.1",
"mui-color-input": "^8.0.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-easy-crop": "^5.5.7",
"react-qr-code": "^2.0.18",
"react-router-dom": "^7.4.0",
"react-router-dom": "^7.13.2",
"react-zoom-pan-pinch": "^3.7.0",
"svg2pdf.js": "^2.5.0"
"svg2pdf.js": "^2.7.0"
},
"devDependencies": {
"@eslint/js": "^9.32.0",
"@types/react": "^19.1.11",
"@types/react-dom": "^19.1.7",
"@vitejs/plugin-react": "^4.7.0",
"eslint": "^9.31.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.38.0",
"vite": "^7.0.6"
"@eslint/js": "^10.0.1",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
"eslint": "^10.1.0",
"eslint-plugin-react-hooks": "0.0.0-experimental-80b1cab3-20260331",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0",
"typescript": "^6.0.2",
"typescript-eslint": "^8.58.0",
"vite": "^8.0.3"
}
}

View File

@@ -152,8 +152,8 @@ export function App(): React.ReactElement {
<Route path="*" element={<NotFoundRoute />} />
</Route>
)}
</>
)
</>,
),
);
return (
@@ -163,6 +163,7 @@ export function App(): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useAuth(): AuthContext {
return React.useContext(AuthContextK)!;
}

View File

@@ -1,12 +1,16 @@
import { AuthApi } from "./AuthApi";
interface APIResponse {
data: any;
data: unknown;
status: number;
}
export class ApiError extends Error {
constructor(message: string, public code: number, public data: any) {
constructor(
message: string,
public code: number,
public data: unknown,
) {
super(message);
}
}
@@ -36,11 +40,11 @@ export class APIClient {
uri: string;
method: "GET" | "POST" | "DELETE" | "PATCH" | "PUT";
allowFail?: boolean;
jsonData?: any;
jsonData?: unknown;
formData?: FormData;
}): Promise<APIResponse> {
let body = undefined;
let headers: any = {
const headers: { [k: string]: string } = {
"X-auth-token": AuthApi.SignedIn ? AuthApi.AuthToken : "none",
};

View File

@@ -42,7 +42,7 @@ export class AuthApi {
*/
static async CreateAccount(
name: string,
mail: string
mail: string,
): Promise<CreateAccountResult> {
const res = await APIClient.exec({
uri: "/auth/create_account",
@@ -77,7 +77,7 @@ export class AuthApi {
*/
static async LoginWithPassword(
mail: string,
password: string
password: string,
): Promise<PasswordLoginResult> {
const res = await APIClient.exec({
uri: "/auth/password_login",
@@ -96,7 +96,10 @@ export class AuthApi {
return PasswordLoginResult.InvalidCredentials;
case 200:
case 201:
localStorage.setItem(TokenStateKey, res.data.token);
localStorage.setItem(
TokenStateKey,
(res.data as { token: string }).token,
);
return PasswordLoginResult.Success;
default:
return PasswordLoginResult.Error;
@@ -115,20 +118,20 @@ export class AuthApi {
method: "POST",
jsonData: { provider: id },
})
).data;
).data as { url: string };
}
/**
* Finish OpenID login
*/
static async FinishOpenIDLogin(code: string, state: string): Promise<void> {
const res: { user_id: number; token: string } = (
const res = (
await APIClient.exec({
uri: "/auth/finish_openid_login",
method: "POST",
jsonData: { code: code, state: state },
})
).data;
).data as { user_id: number; token: string };
localStorage.setItem(TokenStateKey, res.token);
}
@@ -167,7 +170,7 @@ export class AuthApi {
* Check reset password token
*/
static async CheckResetPasswordToken(
token: string
token: string,
): Promise<CheckResetTokenResponse> {
return (
await APIClient.exec({
@@ -175,7 +178,7 @@ export class AuthApi {
method: "POST",
jsonData: { token: token },
})
).data;
).data as CheckResetTokenResponse;
}
/**
@@ -183,7 +186,7 @@ export class AuthApi {
*/
static async ResetPassword(
token: string,
newPassword: string
newPassword: string,
): Promise<void> {
await APIClient.exec({
uri: "/auth/reset_password",

View File

@@ -85,11 +85,17 @@ export class Family implements FamilyAPI {
}
}
interface ExtendedFamilyInfoAPI extends FamilyAPI {
disable_couple_photos: boolean;
enable_genealogy: boolean;
enable_accommodations: boolean;
}
export class ExtendedFamilyInfo extends Family {
public disable_couple_photos: boolean;
public enable_genealogy: boolean;
public enable_accommodations: boolean;
constructor(p: any) {
constructor(p: ExtendedFamilyInfoAPI) {
super(p);
this.disable_couple_photos = p.disable_couple_photos;
this.enable_genealogy = p.enable_genealogy;
@@ -155,12 +161,13 @@ export class FamilyApi {
* Get the list of families
*/
static async GetList(): Promise<Family[]> {
return (
const res = (
await APIClient.exec({
method: "GET",
uri: "/family/list",
})
).data.map((f: FamilyAPI) => new Family(f));
).data as FamilyAPI[];
return res.map((f: FamilyAPI) => new Family(f));
}
/**
@@ -172,7 +179,7 @@ export class FamilyApi {
uri: `/family/${id}`,
});
return new ExtendedFamilyInfo(res.data);
return new ExtendedFamilyInfo(res.data as ExtendedFamilyInfoAPI);
}
/**
@@ -204,7 +211,7 @@ export class FamilyApi {
method: "GET",
uri: `/family/${id}/users`,
})
).data;
).data as FamilyUser[];
}
/**

View File

@@ -74,7 +74,7 @@ export class ServerApi {
uri: "/server/config",
method: "GET",
})
).data;
).data as ServerConfig;
}
/**

View File

@@ -33,7 +33,7 @@ export class UserApi {
uri: "/user/info",
method: "GET",
})
).data;
).data as User;
}
/**
@@ -54,7 +54,7 @@ export class UserApi {
*/
static async ReplacePassword(
oldPwd: string,
newPwd: string
newPwd: string,
): Promise<ReplacePasswordResponse> {
const res = await APIClient.exec({
uri: "/user/replace_password",
@@ -98,7 +98,7 @@ export class UserApi {
* Check delete account token
*/
static async CheckDeleteAccountToken(
token: string
token: string,
): Promise<DeleteAccountTokenInfo> {
return (
await APIClient.exec({
@@ -106,7 +106,7 @@ export class UserApi {
method: "POST",
jsonData: { token: token },
})
).data;
).data as DeleteAccountTokenInfo;
}
/**

View File

@@ -26,7 +26,7 @@ export class AccommodationsList {
}
this.list.sort((a, b) =>
a.name.toLowerCase().localeCompare(b.name.toLocaleLowerCase())
a.name.toLowerCase().localeCompare(b.name.toLocaleLowerCase()),
);
}
@@ -73,7 +73,7 @@ export class AccommodationListApi {
method: "GET",
uri: `/family/${family.family_id}/accommodations/list/list`,
})
).data;
).data as Accommodation[];
return new AccommodationsList(data);
}
@@ -83,7 +83,7 @@ export class AccommodationListApi {
*/
static async Create(
family: Family,
accommodation: UpdateAccommodation
accommodation: UpdateAccommodation,
): Promise<Accommodation> {
return (
await APIClient.exec({
@@ -91,7 +91,7 @@ export class AccommodationListApi {
uri: `/family/${family.family_id}/accommodations/list/create`,
jsonData: accommodation,
})
).data;
).data as Accommodation;
}
/**
@@ -99,7 +99,7 @@ export class AccommodationListApi {
*/
static async Update(
accommodation: Accommodation,
update: UpdateAccommodation
update: UpdateAccommodation,
): Promise<Accommodation> {
return (
await APIClient.exec({
@@ -107,7 +107,7 @@ export class AccommodationListApi {
uri: `/family/${accommodation.family_id}/accommodations/list/${accommodation.id}`,
jsonData: update,
})
).data;
).data as Accommodation;
}
/**
@@ -119,6 +119,6 @@ export class AccommodationListApi {
method: "DELETE",
uri: `/family/${accommodation.family_id}/accommodations/list/${accommodation.id}`,
})
).data;
).data as Accommodation;
}
}

View File

@@ -23,7 +23,7 @@ export class AccommodationsCalendarURLApi {
*/
static async Create(
family: Family,
calendar: NewCalendarURL
calendar: NewCalendarURL,
): Promise<AccommodationCalendarURL> {
return (
await APIClient.exec({
@@ -31,7 +31,7 @@ export class AccommodationsCalendarURLApi {
uri: `/family/${family.family_id}/accommodations/reservations_calendars/create`,
jsonData: calendar,
})
).data;
).data as AccommodationCalendarURL;
}
/**
@@ -50,20 +50,20 @@ export class AccommodationsCalendarURLApi {
method: "GET",
uri: `/family/${family.family_id}/accommodations/reservations_calendars/list`,
})
).data;
).data as AccommodationCalendarURL[];
}
/**
* Delete an accommodation calendar
*/
static async Delete(
calendar: AccommodationCalendarURL
calendar: AccommodationCalendarURL,
): Promise<AccommodationCalendarURL> {
return (
await APIClient.exec({
method: "DELETE",
uri: `/family/${calendar.family_id}/accommodations/reservations_calendars/${calendar.id}`,
})
).data;
).data as AccommodationCalendarURL;
}
}

View File

@@ -48,7 +48,7 @@ export class AccommodationsReservationsList {
}
filter(
predicate: (m: AccommodationReservation) => boolean
predicate: (m: AccommodationReservation) => boolean,
): AccommodationReservation[] {
return this.list.filter(predicate);
}
@@ -75,7 +75,7 @@ export class AccommodationsReservationsApi {
*/
static async Create(
family: Family,
reservation: UpdateAccommodationReservation
reservation: UpdateAccommodationReservation,
): Promise<AccommodationReservation> {
return (
await APIClient.exec({
@@ -86,21 +86,21 @@ export class AccommodationsReservationsApi {
end: reservation.end,
},
})
).data;
).data as AccommodationReservation;
}
/**
* Get the entire list of accommodations of a family
*/
static async FullListOfFamily(
family: Family
family: Family,
): Promise<AccommodationsReservationsList> {
const data = (
await APIClient.exec({
method: "GET",
uri: `/family/${family.family_id}/accommodations/reservations/full_list`,
})
).data;
).data as AccommodationReservation[];
return new AccommodationsReservationsList(data);
}
@@ -112,14 +112,14 @@ export class AccommodationsReservationsApi {
family: Family,
accommodation: Accommodation,
start: number,
end: number
end: number,
): Promise<AccommodationsReservationsList> {
const data = (
await APIClient.exec({
method: "GET",
uri: `/family/${family.family_id}/accommodations/reservations/accommodation/${accommodation.id}/for_interval?start=${start}&end=${end}`,
})
).data;
).data as AccommodationReservation[];
return new AccommodationsReservationsList(data);
}
@@ -129,7 +129,7 @@ export class AccommodationsReservationsApi {
*/
static async Update(
family: Family,
r: UpdateAccommodationReservation
r: UpdateAccommodationReservation,
): Promise<void> {
await APIClient.exec({
method: "PATCH",
@@ -156,7 +156,7 @@ export class AccommodationsReservationsApi {
*/
static async Validate(
r: AccommodationReservation,
accept: boolean
accept: boolean,
): Promise<ValidateResaResult> {
const res = await APIClient.exec({
method: "POST",

View File

@@ -166,7 +166,7 @@ export class CoupleApi {
jsonData: m,
});
return new Couple(res.data);
return new Couple(res.data as CoupleApiInterface);
}
/**
@@ -174,26 +174,28 @@ export class CoupleApi {
*/
static async GetSingle(
family_id: number,
couple_id: number
couple_id: number,
): Promise<Couple> {
const res = await APIClient.exec({
uri: `/family/${family_id}/genealogy/couple/${couple_id}`,
method: "GET",
});
return new Couple(res.data);
return new Couple(res.data as CoupleApiInterface);
}
/**
* Get the entire list of couples of a family
*/
static async GetEntireList(family_id: number): Promise<CouplesList> {
const res = await APIClient.exec({
const res = (
await APIClient.exec({
uri: `/family/${family_id}/genealogy/couples`,
method: "GET",
});
})
).data as CoupleApiInterface[];
return new CouplesList(res.data.map((d: any) => new Couple(d)));
return new CouplesList(res.map((d) => new Couple(d)));
}
/**

View File

@@ -12,7 +12,7 @@ export class DataApi {
uri: `/family/${family_id}/genealogy/data/export`,
method: "GET",
});
return res.data;
return res.data as Blob;
}
/**
@@ -26,6 +26,6 @@ export class DataApi {
method: "PUT",
formData: fd,
});
return res.data;
return res.data as Blob;
}
}

View File

@@ -115,7 +115,7 @@ export class Member implements MemberDataApi {
const firstName = this.first_name ?? "";
return firstName.length === 0
? this.last_name ?? ""
? (this.last_name ?? "")
: `${firstName} ${this.last_name?.toUpperCase() ?? ""}`;
}
@@ -123,7 +123,7 @@ export class Member implements MemberDataApi {
const lastName = this.last_name ?? "";
return lastName.length === 0
? this.last_name ?? ""
? (this.last_name ?? "")
: `${lastName} ${this.first_name ?? ""}`;
}
@@ -164,14 +164,14 @@ export class Member implements MemberDataApi {
}
get displayBirthDeath(): string {
let birthDeath = [];
const birthDeath = [];
if (this.dateOfBirth) birthDeath.push(fmtDate(this.dateOfBirth));
if (this.dateOfDeath) birthDeath.push(fmtDate(this.dateOfDeath));
return birthDeath.join(" - ");
}
get displayBirthDeathShort(): string {
let birthDeath = [];
const birthDeath = [];
if (this.birth_year) birthDeath.push(this.birth_year.toString());
if (this.death_year) birthDeath.push(this.death_year.toString());
return birthDeath.join(" - ");
@@ -226,7 +226,7 @@ export class MembersList {
this.list.sort((a, b) =>
a.invertedFullName
.toLowerCase()
.localeCompare(b.invertedFullName.toLocaleLowerCase())
.localeCompare(b.invertedFullName.toLocaleLowerCase()),
);
}
@@ -257,7 +257,7 @@ export class MembersList {
childrenOfCouple(c: Couple): Member[] {
if (!c.husband && !c.wife) return [];
return this.list.filter(
(m) => m.mother === c.wife && m.father === c.husband
(m) => m.mother === c.wife && m.father === c.husband,
);
}
@@ -267,7 +267,7 @@ export class MembersList {
(m) =>
m.id !== p?.id &&
((m.mother && m.mother === p?.mother) ||
(m.father && m.father === p?.father))
(m.father && m.father === p?.father)),
);
}
}
@@ -277,13 +277,15 @@ export class MemberApi {
* Create a new member
*/
static async Create(m: Member): Promise<Member> {
const res = await APIClient.exec({
const res = (
await APIClient.exec({
uri: `/family/${m.family_id}/genealogy/member/create`,
method: "POST",
jsonData: m,
});
})
).data as MemberDataApi;
return new Member(res.data);
return new Member(res);
}
/**
@@ -291,26 +293,30 @@ export class MemberApi {
*/
static async GetSingle(
family_id: number,
member_id: number
member_id: number,
): Promise<Member> {
const res = await APIClient.exec({
const res = (
await APIClient.exec({
uri: `/family/${family_id}/genealogy/member/${member_id}`,
method: "GET",
});
})
).data as MemberDataApi;
return new Member(res.data);
return new Member(res);
}
/**
* Get the entire list of family members of a family
*/
static async GetEntireList(family_id: number): Promise<MembersList> {
const res = await APIClient.exec({
const res = (
await APIClient.exec({
uri: `/family/${family_id}/genealogy/members`,
method: "GET",
});
})
).data as MemberDataApi[];
return new MembersList(res.data.map((d: any) => new Member(d)));
return new MembersList(res.map((d) => new Member(d)));
}
/**

View File

@@ -27,11 +27,11 @@ export function UpdateAccommodationDialog(p: {
const nameErr = checkConstraint(
ServerApi.Config.constraints.accommodation_name_len,
accommodation?.name
accommodation?.name,
);
const descriptionErr = checkConstraint(
ServerApi.Config.constraints.accommodation_description_len,
accommodation?.description
accommodation?.description,
);
const clearForm = () => {
@@ -49,7 +49,9 @@ export function UpdateAccommodationDialog(p: {
};
React.useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
if (!accommodation) setAccommodation(p.accommodation);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [p.open, p.accommodation]);
return (

View File

@@ -54,10 +54,13 @@ export function UpdateReservationDialog(p: {
};
React.useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
if (!reservation) setReservation(p.reservation);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [p.open, p.reservation]);
React.useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
setConflicts(undefined);
(async () => {
try {
@@ -77,20 +80,21 @@ export function UpdateReservationDialog(p: {
family.family,
accommodations.accommodations.get(reservation.accommodation_id)!,
reservation.start,
reservation.end
reservation.end,
)
).filter(
(r) =>
r.id !== p.reservation?.reservation_id && r.validated !== false
)
r.id !== p.reservation?.reservation_id && r.validated !== false,
),
);
} catch (e) {
console.error(e);
alert(
"Echec de la vérification de la présence de conflits de calendrier !"
"Echec de la vérification de la présence de conflits de calendrier !",
);
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
p.open,
reservation?.accommodation_id,
@@ -118,7 +122,7 @@ export function UpdateReservationDialog(p: {
options={accommodations.accommodations.openToReservationList.map(
(a) => {
return { label: a.name, value: a.id.toString() };
}
},
)}
value={
reservation?.accommodation_id === -1

View File

@@ -63,6 +63,7 @@ export function AlertDialogProvider(p: PropsWithChildren): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useAlert(): AlertContext {
return React.useContext(AlertContextK)!;
}

View File

@@ -11,20 +11,20 @@ import React, { PropsWithChildren } from "react";
type ConfirmContext = (
message: string,
title?: string,
confirmButton?: string
confirmButton?: string,
) => Promise<boolean>;
const ConfirmContextK = React.createContext<ConfirmContext | null>(null);
export function ConfirmDialogProvider(
p: PropsWithChildren
p: PropsWithChildren,
): React.ReactElement {
const [open, setOpen] = React.useState(false);
const [title, setTitle] = React.useState<string | undefined>(undefined);
const [message, setMessage] = React.useState("");
const [confirmButton, setConfirmButton] = React.useState<string | undefined>(
undefined
undefined,
);
const cb = React.useRef<null | ((a: boolean) => void)>(null);
@@ -78,6 +78,7 @@ export function ConfirmDialogProvider(
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useConfirm(): ConfirmContext {
return React.useContext(ConfirmContextK)!;
}

View File

@@ -11,7 +11,7 @@ const darkTheme = createTheme(
mode: "dark",
},
},
dataGridFr
dataGridFr,
);
const lightTheme = createTheme(
@@ -20,7 +20,7 @@ const lightTheme = createTheme(
mode: "light",
},
},
dataGridFr
dataGridFr,
);
interface DarkThemeContext {
@@ -32,7 +32,7 @@ const DarkThemeContextK = React.createContext<DarkThemeContext | null>(null);
export function DarkThemeProvider(p: PropsWithChildren): React.ReactElement {
const [enabled, setEnabled] = React.useState(
localStorage.getItem(localStorageKey) === "true"
localStorage.getItem(localStorageKey) === "true",
);
return (
@@ -52,6 +52,7 @@ export function DarkThemeProvider(p: PropsWithChildren): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useDarkTheme(): DarkThemeContext {
return React.useContext(DarkThemeContextK)!;
}

View File

@@ -15,7 +15,7 @@ const LoadingMessageContextK =
React.createContext<LoadingMessageContext | null>(null);
export function LoadingMessageProvider(
p: PropsWithChildren
p: PropsWithChildren,
): React.ReactElement {
const [open, setOpen] = React.useState(false);
@@ -59,6 +59,7 @@ export function LoadingMessageProvider(
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useLoadingMessage(): LoadingMessageContext {
return React.useContext(LoadingMessageContextK)!;
}

View File

@@ -38,6 +38,7 @@ export function SnackbarProvider(p: PropsWithChildren): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useSnackbar(): SnackbarContext {
return React.useContext(SnackbarContextK)!;
}

View File

@@ -7,12 +7,12 @@ type DialogContext = () => Promise<NewCalendarURL | undefined>;
const DialogContextK = React.createContext<DialogContext | null>(null);
export function CreateAccommodationCalendarURLDialogProvider(
p: PropsWithChildren
p: PropsWithChildren,
): React.ReactElement {
const [open, setOpen] = React.useState(false);
const cb = React.useRef<null | ((a: NewCalendarURL | undefined) => void)>(
null
null,
);
const handleClose = (res?: NewCalendarURL) => {
@@ -47,6 +47,7 @@ export function CreateAccommodationCalendarURLDialogProvider(
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useCreateAccommodationCalendarURL(): DialogContext {
return React.useContext(DialogContextK)!;
}

View File

@@ -7,7 +7,7 @@ type DialogContext = (cal: AccommodationCalendarURL) => Promise<void>;
const DialogContextK = React.createContext<DialogContext | null>(null);
export function InstallCalendarDialogProvider(
p: PropsWithChildren
p: PropsWithChildren,
): React.ReactElement {
const [cal, setCal] = React.useState<AccommodationCalendarURL | undefined>();
@@ -39,6 +39,7 @@ export function InstallCalendarDialogProvider(
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useInstallCalendarDialog(): DialogContext {
return React.useContext(DialogContextK)!;
}

View File

@@ -4,13 +4,13 @@ import { UpdateAccommodationDialog } from "../../../dialogs/accommodations/Updat
type DialogContext = (
accommodation: UpdateAccommodation,
create: boolean
create: boolean,
) => Promise<UpdateAccommodation | undefined>;
const DialogContextK = React.createContext<DialogContext | null>(null);
export function UpdateAccommodationDialogProvider(
p: PropsWithChildren
p: PropsWithChildren,
): React.ReactElement {
const [open, setOpen] = React.useState(false);
@@ -59,6 +59,7 @@ export function UpdateAccommodationDialogProvider(
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useUpdateAccommodation(): DialogContext {
return React.useContext(DialogContextK)!;
}

View File

@@ -4,13 +4,13 @@ import { UpdateReservationDialog } from "../../../dialogs/accommodations/UpdateR
type DialogContext = (
reservation: UpdateAccommodationReservation,
create: boolean
create: boolean,
) => Promise<UpdateAccommodationReservation | undefined>;
const DialogContextK = React.createContext<DialogContext | null>(null);
export function UpdateReservationDialogProvider(
p: PropsWithChildren
p: PropsWithChildren,
): React.ReactElement {
const [open, setOpen] = React.useState(false);
@@ -59,6 +59,7 @@ export function UpdateReservationDialogProvider(
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useUpdateAccommodationReservation(): DialogContext {
return React.useContext(DialogContextK)!;
}

View File

@@ -48,12 +48,13 @@ export function FamiliesListRoute(): React.ReactElement {
return (
<AsyncWidget
ready={families !== null}
// eslint-disable-next-line react-hooks/refs
loadKey={`families-list-${loadKey.current}`}
load={load}
errMsg="Echec du chargement de la liste des familles"
build={() => (
<>
{families!!.length === 0 ? (
{families!.length === 0 ? (
<NoFamilyWidget
onRequestCreateFamily={onRequestCreateFamily}
onRequestJoinFamily={onRequestJoinFamily}
@@ -190,7 +191,7 @@ function FamilyCard(p: {
if (
!p.f.CanLeave ||
!(await confirm(
"Voulez-vous vraiment quitter la famille " + p.f.name + " ?"
"Voulez-vous vraiment quitter la famille " + p.f.name + " ?",
))
)
return;
@@ -200,7 +201,7 @@ function FamilyCard(p: {
p.onFamilyLeft();
alert(
`La famille ${p.f.name} a été retirée de votre liste de familles !`
`La famille ${p.f.name} a été retirée de votre liste de familles !`,
);
} catch (e) {
console.error(e);

View File

@@ -14,10 +14,10 @@ import React from "react";
import { ServerApi } from "../api/ServerApi";
import { ReplacePasswordResponse, User, UserApi } from "../api/UserApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useUser } from "../widgets/BaseAuthenticatedPage";
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
import { formatDate } from "../utils/time_utils";
import { useUser } from "../widgets/BaseAuthenticatedPage";
import { PasswordInput } from "../widgets/PasswordInput";
import { formatDate } from "../widgets/TimeWidget";
export function ProfileRoute(): React.ReactElement {
const user = useUser();
@@ -172,7 +172,7 @@ function ChangePasswordCard(): React.ReactElement {
break;
case ReplacePasswordResponse.TooManyRequests:
setError(
"Trop de tentatives de changement de mot de passe, veuillez réessayer ultérieurement !"
"Trop de tentatives de changement de mot de passe, veuillez réessayer ultérieurement !",
);
break;
}
@@ -257,7 +257,7 @@ function DeleteAccountButton(): React.ReactElement {
if (
!(await confirm(
"Voulez-vous initier la suppression de votre compte ?",
"Suppression de compte"
"Suppression de compte",
))
)
return;
@@ -265,7 +265,7 @@ function DeleteAccountButton(): React.ReactElement {
await UserApi.RequestAccountDeletion();
await alert(
"Demande de suppression de compte enregistrée avec succès. Veuillez consulter votre boîte mail."
"Demande de suppression de compte enregistrée avec succès. Veuillez consulter votre boîte mail.",
);
} catch (e) {
console.error(e);

View File

@@ -40,7 +40,7 @@ export function LoginRoute(): React.ReactElement {
const handleClickShowPassword = () => setShowPassword((show) => !show);
const handleMouseDownPassword = (
event: React.MouseEvent<HTMLButtonElement>
event: React.MouseEvent<HTMLButtonElement>,
) => {
event.preventDefault();
};
@@ -55,7 +55,7 @@ export function LoginRoute(): React.ReactElement {
switch (res) {
case PasswordLoginResult.TooManyRequests:
setError(
"Trop de tentatives de connection. Veuillez réessayer ultérieurement."
"Trop de tentatives de connection. Veuillez réessayer ultérieurement.",
);
break;
@@ -84,6 +84,7 @@ export function LoginRoute(): React.ReactElement {
setLoading(true);
const res = await AuthApi.StartOpenIDLogin(id);
// eslint-disable-next-line react-hooks/immutability
window.location.href = res.url;
} catch (e) {
console.error(e);

View File

@@ -14,9 +14,9 @@ import { FamilyApi } from "../../api/FamilyApi";
import { ServerApi } from "../../api/ServerApi";
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
import { formatDate } from "../../utils/time_utils";
import { useFamily } from "../../widgets/BaseFamilyRoute";
import { FamilyCard } from "../../widgets/FamilyCard";
import { formatDate } from "../../widgets/TimeWidget";
export function FamilySettingsRoute(): React.ReactElement {
const alert = useAlert();
@@ -29,7 +29,7 @@ export function FamilySettingsRoute(): React.ReactElement {
try {
if (
!(await confirm(
"Voulez-vous vraiment supprimer cette famille, et toute les données qui s'y rattachent ? Cette opération est absolument irréversible !"
"Voulez-vous vraiment supprimer cette famille, et toute les données qui s'y rattachent ? Cette opération est absolument irréversible !",
))
)
return;
@@ -69,10 +69,10 @@ function FamilySettingsCard(): React.ReactElement {
const [newName, setNewName] = React.useState(family.family.name);
const [enableGenealogy, setEnableGenealogy] = React.useState(
family.family.enable_genealogy
family.family.enable_genealogy,
);
const [enableAccommodations, setEnableAccommodations] = React.useState(
family.family.enable_accommodations
family.family.enable_accommodations,
);
const canEdit = family.family.is_admin;

View File

@@ -38,6 +38,7 @@ export function FamilyUsersListRoute(): React.ReactElement {
return (
<AsyncWidget
// eslint-disable-next-line react-hooks/refs
loadKey={`${family.family.family_id}-${key.current}`}
errMsg="Echec du chargement de la liste des utilisateurs de la famille !"
load={load}
@@ -62,7 +63,7 @@ function UsersTable(p: {
const family = useFamily();
const [rowModesModel, setRowModesModel] = React.useState<GridRowModesModel>(
{}
{},
);
const handleEditClick = (id: GridRowId) => () => {
@@ -79,7 +80,7 @@ function UsersTable(p: {
const user = p.users.find((u) => u.user_id === id)!;
if (
!(await confirm(
`Voulez-vous vraiment retirer ${user.user_name} de cette famille ?`
`Voulez-vous vraiment retirer ${user.user_name} de cette famille ?`,
))
)
return;
@@ -137,8 +138,10 @@ function UsersTable(p: {
<GridActionsCellItem
icon={<SaveIcon />}
label="Save"
sx={{
material={{
sx: {
color: "primary.main",
},
}}
onClick={handleSaveClick(id)}
/>,

View File

@@ -74,7 +74,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
const [showPending, setShowPending] = React.useState(true);
const [hiddenPeople, setHiddenPeople] = React.useState<Set<number>>(
new Set()
new Set(),
);
const [hiddenAccommodations, setHiddenAccommodations] = React.useState<
Set<number>
@@ -100,7 +100,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
const load = async () => {
setReservations(
await AccommodationsReservationsApi.FullListOfFamily(family.family)
await AccommodationsReservationsApi.FullListOfFamily(family.family),
);
setUsers(await FamilyApi.GetUsersList(family.family.family_id));
};
@@ -136,7 +136,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
start: Math.floor(d.start.getTime() / 1000),
end: Math.floor(d.end.getTime() / 1000),
},
true
true,
);
if (!resa) return;
@@ -157,7 +157,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
const onEventClick = (ev: EventClickArg) => {
const id: number = ev.event.extendedProps.id;
const resa = reservations?.get(id)!;
const resa = reservations!.get(id)!;
const acc = accommodations.accommodations.get(resa.accommodation_id)!;
const user = users?.find((u) => u.user_id === resa.user_id);
@@ -182,7 +182,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
const respondToResaRequest = async (
r: AccommodationReservation,
validate: boolean
validate: boolean,
) => {
try {
loadingMessage.show("Validation de la réservation en cours...");
@@ -194,7 +194,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
if (res === ValidateResaResult.Conflict) {
throw new Error(
"The reservation is in conflict with other reservations!"
"The reservation is in conflict with other reservations!",
);
} else if (res === ValidateResaResult.Error) {
throw new Error("Failed to validate the reservation!");
@@ -217,7 +217,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
const rejectReservation = async (r: AccommodationReservation) => {
if (
!(await confirm(
"Voulez-vous vraiment rejeter cette demande de réservation ?"
"Voulez-vous vraiment rejeter cette demande de réservation ?",
))
)
return;
@@ -230,7 +230,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
if (
ac?.need_validation &&
!(await confirm(
"Voulez-vous vraiment changer cette réservation ? Celle-ci devra être de nouveau validée !"
"Voulez-vous vraiment changer cette réservation ? Celle-ci devra être de nouveau validée !",
))
)
return;
@@ -242,7 +242,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
start: r.reservation_start,
end: r.reservation_end,
},
false
false,
);
if (!newResa) return;
@@ -266,7 +266,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
try {
if (
!(await confirm(
"Voulez-vous vraiment supprimer cette réservation ? L'opération n'est pas réversible !"
"Voulez-vous vraiment supprimer cette réservation ? L'opération n'est pas réversible !",
))
)
return;
@@ -290,6 +290,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
<>
<FamilyPageTitle title="Réservations" />
<AsyncWidget
// eslint-disable-next-line react-hooks/refs
loadKey={loadKey.current}
load={load}
errMsg="Echec du chargement de la liste des réservations !"
@@ -365,7 +366,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
if (v) hiddenAccommodations.delete(a.id);
else hiddenAccommodations.add(a.id);
setHiddenAccommodations(
new Set(hiddenAccommodations)
new Set(hiddenAccommodations),
);
}}
/>
@@ -422,7 +423,7 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
eventClick={onEventClick}
events={visibleReservations?.map((r) => {
const a = accommodations.accommodations.get(
r.accommodation_id
r.accommodation_id,
)!;
const u = users?.find((u) => u.user_id === r.user_id);
return {
@@ -493,12 +494,12 @@ export function AccommodationsReservationsRoute(): React.ReactElement {
<p>
Du{" "}
{fmtUnixDate(
activeEvent?.reservation.reservation_start ?? 0
activeEvent?.reservation.reservation_start ?? 0,
)}{" "}
<br />
Au{" "}
{fmtUnixDate(
activeEvent?.reservation.reservation_end ?? 0
activeEvent?.reservation.reservation_end ?? 0,
)}
</p>
<p>

View File

@@ -66,7 +66,7 @@ function AccommodationsListCard(): React.ReactElement {
need_validation: false,
color: "2196f3",
},
true
true,
);
if (!accommodation) return;
@@ -112,7 +112,7 @@ function AccommodationsListCard(): React.ReactElement {
try {
if (
!(await confirm(
`Voulez-vous vraiment supprimer le logement '${a.name}' ? Cette opération est définitive !`
`Voulez-vous vraiment supprimer le logement '${a.name}' ? Cette opération est définitive !`,
))
)
return;
@@ -258,7 +258,7 @@ function AccommodationsCalURLsCard(): React.ReactElement {
try {
if (
!(await confirm(
`Voulez-vous vraiment supprimer le calendrier '${c.name}' ? Cette opération est définitive !`
`Voulez-vous vraiment supprimer le calendrier '${c.name}' ? Cette opération est définitive !`,
))
)
return;
@@ -287,7 +287,7 @@ function AccommodationsCalURLsCard(): React.ReactElement {
const cal = await AccommodationsCalendarURLApi.Create(
family.family,
newCal
newCal,
);
setSuccess("Le calendrier a été créé avec succès !");
@@ -337,6 +337,7 @@ function AccommodationsCalURLsCard(): React.ReactElement {
<AsyncWidget
ready={list !== undefined}
// eslint-disable-next-line react-hooks/refs
loadKey={key.current}
load={load}
errMsg="Echec du chargement de la liste des calendriers !"

View File

@@ -1,3 +1,4 @@
/* eslint-disable react-hooks/immutability */
import ClearIcon from "@mui/icons-material/Clear";
import DeleteIcon from "@mui/icons-material/Delete";
import EditIcon from "@mui/icons-material/Edit";
@@ -111,7 +112,7 @@ export function FamilyCoupleRoute(): React.ReactElement {
try {
if (
!(await confirm(
"Voulez-vous vraiment supprimer cette fiche de couple ? L'opération n'est pas réversible !"
"Voulez-vous vraiment supprimer cette fiche de couple ? L'opération n'est pas réversible !",
))
)
return;
@@ -130,6 +131,7 @@ export function FamilyCoupleRoute(): React.ReactElement {
return (
<AsyncWidget
// eslint-disable-next-line react-hooks/refs
loadKey={`${coupleId}-${count.current}`}
load={load}
ready={couple !== undefined}
@@ -230,7 +232,7 @@ export function CouplePage(p: {
const [changed, setChanged] = React.useState(false);
const [couple, setCouple] = React.useState(
new Couple(structuredClone(p.couple))
new Couple(structuredClone(p.couple)),
);
const updatedCouple = () => {
@@ -240,7 +242,7 @@ export function CouplePage(p: {
const save = async () => {
loadingMessage.show(
"Enregistrement des informations du couple en cours..."
"Enregistrement des informations du couple en cours...",
);
await p.onSave!(couple);
loadingMessage.hide();
@@ -250,7 +252,7 @@ export function CouplePage(p: {
if (
changed &&
!(await confirm(
"Voulez-vous vraiment retirer les modifications apportées ? Celles-ci seront perdues !"
"Voulez-vous vraiment retirer les modifications apportées ? Celles-ci seront perdues !",
))
)
return;
@@ -491,7 +493,7 @@ export function CouplePage(p: {
<div style={{ display: "flex", justifyContent: "end" }}>
<RouterLink
to={family.family.URL(
`genealogy/member/create?mother=${couple.wife}&father=${couple.husband}`
`genealogy/member/create?mother=${couple.wife}&father=${couple.husband}`,
)}
>
<Button>Nouveau</Button>

View File

@@ -1,5 +1,6 @@
/* eslint-disable react-hooks/immutability */
import { mdiFamilyTree } from "@mdi/js";
import Icon from "@mdi/react";
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";
@@ -125,7 +126,7 @@ export function FamilyMemberRoute(): React.ReactElement {
try {
if (
!(await confirm(
"Voulez-vous vraiment supprimer cette fiche membre ? L'opération n'est pas réversible !"
"Voulez-vous vraiment supprimer cette fiche membre ? L'opération n'est pas réversible !",
))
)
return;
@@ -144,6 +145,7 @@ export function FamilyMemberRoute(): React.ReactElement {
return (
<AsyncWidget
// eslint-disable-next-line react-hooks/refs
loadKey={`${memberId}-${count.current}`}
load={load}
ready={member !== undefined}
@@ -250,7 +252,7 @@ export function MemberPage(p: {
const [changed, setChanged] = React.useState(false);
const [member, setMember] = React.useState(
new Member(structuredClone(p.member))
new Member(structuredClone(p.member)),
);
const updatedMember = () => {
@@ -260,7 +262,7 @@ export function MemberPage(p: {
const save = async () => {
loadingMessage.show(
"Enregistrement des informations du membre en cours..."
"Enregistrement des informations du membre en cours...",
);
await p.onSave!(member);
loadingMessage.hide();
@@ -270,7 +272,7 @@ export function MemberPage(p: {
if (
changed &&
!(await confirm(
"Voulez-vous vraiment retirer les modifications apportées ? Celles-ci seront perdues !"
"Voulez-vous vraiment retirer les modifications apportées ? Celles-ci seront perdues !",
))
)
return;
@@ -666,7 +668,7 @@ export function MemberPage(p: {
to={family.family.URL(
`genealogy/couple/create?${
member.sex === "F" ? "wife" : "husband"
}=${member.id}`
}=${member.id}`,
)}
>
<Button>Nouveau</Button>
@@ -695,7 +697,7 @@ export function MemberPage(p: {
to={family.family.URL(
`genealogy/member/create?${
member.sex === "F" ? "mother" : "father"
}=${member.id}`
}=${member.id}`,
)}
>
<Button>Nouveau</Button>
@@ -723,7 +725,7 @@ export function MemberPage(p: {
<div style={{ display: "flex", justifyContent: "end" }}>
<RouterLink
to={family.family.URL(
`genealogy/member/create?mother=${member.mother}&father=${member.father}`
`genealogy/member/create?mother=${member.mother}&father=${member.father}`,
)}
>
<Button>Nouveau</Button>
@@ -748,7 +750,7 @@ function CoupleItem(p: {
const genealogy = useGenealogy();
const statusStr = ServerApi.Config.couples_states.find(
(c) => c.code === p.couple.state
(c) => c.code === p.couple.state,
)?.fr;
const status = [];

View File

@@ -20,7 +20,7 @@ export function getRadianAngle(degreeValue: number): number {
export function rotateSize(
width: number,
height: number,
rotation: number
rotation: number,
): { width: number; height: number } {
const rotRad = getRadianAngle(rotation);
@@ -39,7 +39,7 @@ export default async function getCroppedImg(
imageSrc: string,
pixelCrop: Area,
rotation = 0,
flip = { horizontal: false, vertical: false }
flip = { horizontal: false, vertical: false },
): Promise<Blob> {
const image = await createImage(imageSrc);
const canvas = document.createElement("canvas");
@@ -55,7 +55,7 @@ export default async function getCroppedImg(
const { width: bBoxWidth, height: bBoxHeight } = rotateSize(
image.width,
image.height,
rotation
rotation,
);
// set canvas size to match the bounding box
@@ -93,14 +93,14 @@ export default async function getCroppedImg(
0,
0,
pixelCrop.width,
pixelCrop.height
pixelCrop.height,
);
// As Base64 string
// return croppedCanvas.toDataURL('image/jpeg');
// As a blob
return await new Promise((resolve, _reject) => {
return await new Promise((resolve) => {
croppedCanvas.toBlob((file) => {
resolve(file!);
}, "image/jpeg");

View File

@@ -14,8 +14,8 @@ export async function selectFileToUpload(p: {
fileEl.click();
// Wait for a file to be chosen
await new Promise((res, _rej) =>
fileEl.addEventListener("change", () => res(null))
await new Promise((res) =>
fileEl.addEventListener("change", () => res(null)),
);
if ((fileEl.files?.length ?? 0) === 0) return null;
@@ -25,8 +25,8 @@ export async function selectFileToUpload(p: {
if (p.maxSize && file.size > p.maxSize) {
throw new Error(
`Le fichier sélectionné est trop lourd ! (taille maximale acceptée : ${filesize(
p.maxSize
)})`
p.maxSize,
)})`,
);
}

View File

@@ -1,5 +1,5 @@
let canvas: HTMLCanvasElement = document.createElement("canvas");
let charLen: Map<string, Map<string, number>> = new Map();
const canvas: HTMLCanvasElement = document.createElement("canvas");
const charLen: Map<string, Map<string, number>> = new Map();
/**
* Uses canvas.measureText to compute and return the width of the given text of given font in pixels.

View File

@@ -1,6 +1,6 @@
export function getAllIndexes(s: string, val: string) {
var indexes = [],
i = -1;
export function getAllIndexes(s: string, val: string): number[] {
const indexes = [];
let i = -1;
while ((i = s.indexOf(val, i + 1)) !== -1) {
indexes.push(i);
}

View File

@@ -1,3 +1,5 @@
import { format } from "date-and-time";
/**
* Get formatted UNIX date
*/
@@ -10,7 +12,7 @@ export function fmtUnixDate(time: number): string {
*/
export function fmtUnixDateFullCalendar(
time: number,
correctEnd: boolean
correctEnd: boolean,
): string {
let d = new Date(time * 1000);
@@ -29,3 +31,65 @@ export function fmtUnixDateFullCalendar(
return s;
}
/**
* Format a date into a human-readable form
*/
export function formatDate(time: number): string {
const t = new Date();
t.setTime(1000 * time);
return format(t, "DD/MM/YYYY HH:mm:ss");
}
/**
* Get human readable time between to dates
*/
export function timeDiff(a: number, b: number): string {
let diff = b - a;
if (diff === 0) return "maintenant";
if (diff === 1) return "1 seconde";
if (diff < 60) {
return `${diff} secondes`;
}
diff = Math.floor(diff / 60);
if (diff === 1) return "1 minute";
if (diff < 24) {
return `${diff} minutes`;
}
diff = Math.floor(diff / 60);
if (diff === 1) return "1 heure";
if (diff < 24) {
return `${diff} heures`;
}
const diffDays = Math.floor(diff / 24);
if (diffDays === 1) return "1 jour";
if (diffDays < 31) {
return `${diffDays} jours`;
}
diff = Math.floor(diffDays / 31);
if (diff < 12) {
return `${diff} mois`;
}
const diffYears = Math.floor(diffDays / 365);
if (diffYears === 1) return "1 an";
return `${diffYears} ans`;
}
/**
* Get human readable time diff from a given timestamp to today
*/
export function timeDiffFromNow(time: number): string {
return timeDiff(time, Math.floor(new Date().getTime() / 1000));
}

View File

@@ -1,23 +1,23 @@
import { Alert, Box, Button, CircularProgress } from "@mui/material";
import { useEffect, useRef, useState } from "react";
import React from "react";
enum State {
Loading,
Ready,
Error,
}
const State = {
Loading: 0,
Ready: 1,
Error: 2,
} as const;
type State = keyof typeof State;
export function AsyncWidget(p: {
loadKey: any;
loadKey: unknown;
load: () => Promise<void>;
errMsg: string;
build: () => React.ReactElement;
ready?: boolean;
errAdditionalElement?: () => React.ReactElement;
}): React.ReactElement {
const [state, setState] = useState(State.Loading);
const counter = useRef<any | null>(null);
const [state, setState] = React.useState<number>(State.Loading);
const load = async () => {
try {
@@ -30,12 +30,11 @@ export function AsyncWidget(p: {
}
};
useEffect(() => {
if (counter.current === p.loadKey) return;
counter.current = p.loadKey;
React.useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
load();
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [p.loadKey]);
if (state === State.Error)
return (
@@ -48,10 +47,6 @@ export function AsyncWidget(p: {
height: "100%",
flex: "1",
flexDirection: "column",
backgroundColor: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[900],
}}
>
<Alert
@@ -64,7 +59,7 @@ export function AsyncWidget(p: {
<Button onClick={load}>Réessayer</Button>
{p.errAdditionalElement && p.errAdditionalElement()}
{p.errAdditionalElement?.()}
</Box>
);
@@ -78,10 +73,6 @@ export function AsyncWidget(p: {
alignItems: "center",
height: "100%",
flex: "1",
backgroundColor: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[900],
}}
>
<CircularProgress />

View File

@@ -1,5 +1,5 @@
import { mdiFamilyTree } from "@mdi/js";
import Icon from "@mdi/react";
import { Icon } from "@mdi/react";
import SettingsIcon from "@mui/icons-material/Settings";
import { Box, Button } from "@mui/material";
import AppBar from "@mui/material/AppBar";
@@ -150,6 +150,7 @@ export function BaseAuthenticatedPage(): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useUser(): UserContext {
return React.useContext(UserContextK)!;
}

View File

@@ -11,7 +11,7 @@ import {
mdiPlus,
mdiRefresh,
} from "@mdi/js";
import Icon from "@mdi/react";
import { Icon } from "@mdi/react";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
import HomeIcon from "@mui/icons-material/Home";
import {
@@ -65,7 +65,7 @@ export function BaseFamilyRoute(): React.ReactElement {
loadKey.current += 1;
setFamily(null);
return new Promise<void>((res, _rej) => {
return new Promise<void>((res) => {
loadPromise.current = () => res();
});
};
@@ -79,7 +79,7 @@ export function BaseFamilyRoute(): React.ReactElement {
try {
if (
!(await confirm(
"Voulez-vous vraiment générer un nouveau code d'invitation pour cette famille ? Cette action aura pour effet d'invalider l'ancien code !"
"Voulez-vous vraiment générer un nouveau code d'invitation pour cette famille ? Cette action aura pour effet d'invalider l'ancien code !",
))
)
return;
@@ -98,6 +98,7 @@ export function BaseFamilyRoute(): React.ReactElement {
return (
<AsyncWidget
ready={family !== null}
// eslint-disable-next-line react-hooks/refs
loadKey={`${familyId}-${loadKey.current}`}
load={load}
errMsg="Échec du chargement des informations de la famille !"
@@ -287,6 +288,7 @@ export function BaseFamilyRoute(): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useFamily(): FamilyContext {
return React.useContext(FamilyContextK)!;
}

View File

@@ -1,5 +1,5 @@
import { mdiFamilyTree } from "@mdi/js";
import Icon from "@mdi/react";
import { Icon } from "@mdi/react";
import Avatar from "@mui/material/Avatar";
import Box from "@mui/material/Box";
import CssBaseline from "@mui/material/CssBaseline";
@@ -9,14 +9,14 @@ import Typography from "@mui/material/Typography";
import { Link, Outlet } from "react-router-dom";
import { DarkThemeButton } from "./DarkThemeButton";
function Copyright(props: any) {
function Copyright(): React.ReactElement {
return (
<Typography
variant="body2"
color="text.secondary"
align="center"
style={{ marginTop: "20px" }}
{...props}
sx={{ mt: 5 }}
>
{"Copyright © "}
<a
@@ -90,7 +90,7 @@ export function BaseLoginPage() {
{/* inner page */}
<Outlet />
<Copyright sx={{ mt: 5 }} />
<Copyright />
</Box>
</Grid>
</Grid>

View File

@@ -1,5 +1,5 @@
import { mdiBabyCarriage, mdiCross } from "@mdi/js";
import Icon from "@mdi/react";
import { Icon } from "@mdi/react";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { TreeItem, SimpleTreeView } from "@mui/x-tree-view";

View File

@@ -16,7 +16,7 @@ import { useBlocker } from "react-router-dom";
export function ConfirmLeaveWithoutSaveDialog(p: {
shouldBlock: boolean;
}): React.ReactElement {
let blocker = useBlocker(p.shouldBlock);
const blocker = useBlocker(p.shouldBlock);
React.useEffect(() => {
if (blocker.state === "blocked" && !p.shouldBlock) {
@@ -49,8 +49,8 @@ export function ConfirmLeaveWithoutSaveDialog(p: {
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={confirmNavigation as any}>Quitter la page</Button>
<Button onClick={cancelNavigation as any} autoFocus>
<Button onClick={confirmNavigation}>Quitter la page</Button>
<Button onClick={cancelNavigation} autoFocus>
Rester sur la page
</Button>
</DialogActions>

View File

@@ -7,7 +7,7 @@ import {
} from "@mui/material";
import { Member, fmtDate } from "../api/genealogy/MemberApi";
import { MemberPhoto } from "./MemberPhoto";
import Icon from "@mdi/react";
import { Icon } from "@mdi/react";
import FemaleIcon from "@mui/icons-material/Female";
import MaleIcon from "@mui/icons-material/Male";
@@ -37,7 +37,7 @@ export function MemberItem(p: {
secondary={
p.member?.dead
? `${fmtDate(p.member?.dateOfBirth)} - ${fmtDate(
p.member?.dateOfDeath
p.member?.dateOfDeath,
)}`
: fmtDate(p.member?.dateOfBirth)
}

View File

@@ -1,58 +1,5 @@
import { Tooltip } from "@mui/material";
import date from "date-and-time";
export function formatDate(time: number): string {
const t = new Date();
t.setTime(1000 * time);
return date.format(t, "DD/MM/YYYY HH:mm:ss");
}
export function timeDiff(a: number, b: number): string {
let diff = b - a;
if (diff === 0) return "maintenant";
if (diff === 1) return "1 seconde";
if (diff < 60) {
return `${diff} secondes`;
}
diff = Math.floor(diff / 60);
if (diff === 1) return "1 minute";
if (diff < 24) {
return `${diff} minutes`;
}
diff = Math.floor(diff / 60);
if (diff === 1) return "1 heure";
if (diff < 24) {
return `${diff} heures`;
}
const diffDays = Math.floor(diff / 24);
if (diffDays === 1) return "1 jour";
if (diffDays < 31) {
return `${diffDays} jours`;
}
diff = Math.floor(diffDays / 31);
if (diff < 12) {
return `${diff} mois`;
}
const diffYears = Math.floor(diffDays / 365);
if (diffYears === 1) return "1 an";
return `${diffYears} ans`;
}
export function timeDiffFromNow(time: number): string {
return timeDiff(time, Math.floor(new Date().getTime() / 1000));
}
import { formatDate, timeDiffFromNow } from "../utils/time_utils";
export function TimeWidget(p: { time: number }): React.ReactElement {
return (

View File

@@ -31,7 +31,7 @@ export function BaseAccommodationsRoute(): React.ReactElement {
const load = async () => {
setAccommodations(
await AccommodationListApi.GetListOfFamily(family.family)
await AccommodationListApi.GetListOfFamily(family.family),
);
};
@@ -39,7 +39,7 @@ export function BaseAccommodationsRoute(): React.ReactElement {
loadKey.current += 1;
setAccommodations(null);
return new Promise<void>((res, _rej) => {
return new Promise<void>((res) => {
loadPromise.current = () => res();
});
};
@@ -47,6 +47,7 @@ export function BaseAccommodationsRoute(): React.ReactElement {
return (
<AsyncWidget
ready={accommodations !== null}
// eslint-disable-next-line react-hooks/refs
loadKey={`${family.familyId}-${loadKey.current}`}
load={load}
errMsg="Échec du chargement des informations sur les logements de la famille !"
@@ -79,6 +80,7 @@ export function BaseAccommodationsRoute(): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useAccommodations(): AccommodationsContext {
return React.useContext(AccommodationsContextK)!;
}

View File

@@ -58,7 +58,7 @@ export function MemberInput(p: {
return (
<Autocomplete
value={p.current ? genealogy.members.get(p.current) : undefined}
onChange={(_event: any, newValue: Member | null | undefined) => {
onChange={(_event: unknown, newValue: Member | null | undefined) => {
p.onValueChange(newValue?.id);
}}
inputValue={inputValue}
@@ -69,14 +69,14 @@ export function MemberInput(p: {
sx={{ width: "100%" }}
filterOptions={(options, state) => {
const res = options.filter((m) =>
m?.fullName.toLowerCase().includes(state.inputValue)
m?.fullName.toLowerCase().includes(state.inputValue),
);
res.length = Math.min(20, res.length);
return res;
}}
getOptionLabel={(o) => o?.fullName ?? ""}
renderInput={(params) => <TextField {...params} label={p.label} />}
renderOption={(_props, option, _state) => (
renderOption={(_props, option) => (
<MemberItem
member={option}
onClick={() => p.onValueChange(option?.id)}

View File

@@ -34,7 +34,7 @@ export function BaseGenealogyRoute(): React.ReactElement {
setMembers(null);
setCouples(null);
return new Promise<void>((res, _rej) => {
return new Promise<void>((res) => {
loadPromise.current = () => res();
});
};
@@ -42,6 +42,7 @@ export function BaseGenealogyRoute(): React.ReactElement {
return (
<AsyncWidget
ready={members !== null && couples !== null}
// eslint-disable-next-line react-hooks/refs
loadKey={`${family.familyId}-${loadKey.current}`}
load={load}
errMsg="Échec du chargement des informations de généalogie de la famille !"
@@ -68,6 +69,7 @@ export function BaseGenealogyRoute(): React.ReactElement {
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useGenealogy(): GenealogyContext {
return React.useContext(GenealogyContextK)!;
}

View File

@@ -1,5 +1,5 @@
import { mdiXml } from "@mdi/js";
import Icon from "@mdi/react";
import { Icon } from "@mdi/react";
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
import { IconButton, Tooltip } from "@mui/material";
import jsPDF from "jspdf";
@@ -89,7 +89,7 @@ function center(container_width: number, el_width: number): number {
function buildSimpleTreeNode(
tree: FamilyTreeNode,
depth: number
depth: number,
): SimpleTreeNode {
if (depth === 0) throw new Error("Too much recursion reached!");
@@ -100,7 +100,7 @@ function buildSimpleTreeNode(
let childrenToProcess = tree.down;
if (depth > 1)
tree.couples?.forEach(
(c) => (childrenToProcess = childrenToProcess?.concat(c.down))
(c) => (childrenToProcess = childrenToProcess?.concat(c.down)),
);
else childrenToProcess = [];
@@ -156,7 +156,7 @@ export function SimpleFamilyTree(p: {
const tree = React.useMemo(
() => buildSimpleTreeNode(p.tree, p.depth),
[p.tree, p.depth]
[p.tree, p.depth],
);
const height = p.depth * (CARD_HEIGHT + LEVEL_SPACING) - LEVEL_SPACING;
@@ -250,44 +250,42 @@ function NodeArea(p: {
childrenLinkDestY?: number;
node: SimpleTreeNode;
}): React.ReactElement {
let parent_x_offset: number;
let pers1 = p.node.member;
let pers2 = p.node.spouse?.member;
let didSwap = false;
// Show male of the left (all the time)
if (pers2?.sex === "M") {
let s = pers1;
const s = pers1;
pers1 = pers2;
pers2 = s;
didSwap = true;
}
parent_x_offset = p.x + center(p.node.width, p.node.parentWidth);
const parent_x_offset = p.x + center(p.node.width, p.node.parentWidth);
let unusedChildrenWidth = p.node.width - p.node.childrenWidth;
const unusedChildrenWidth = p.node.width - p.node.childrenWidth;
let downXOffset = p.x + Math.floor(unusedChildrenWidth / 2);
let endFirstFaceX =
const endFirstFaceX =
parent_x_offset +
Math.floor((memberCardWidth(pers1) - FACE_WIDTH) / 2) +
FACE_WIDTH;
let beginingOfSecondCardX =
const beginingOfSecondCardX =
parent_x_offset + p.node.parentWidth - memberCardWidth(pers2);
let beginSecondFaceX =
const beginSecondFaceX =
p.node.spouse &&
beginingOfSecondCardX + (memberCardWidth(pers2) - FACE_WIDTH) / 2;
let middleParentFaceY = p.y + Math.floor(FACE_HEIGHT / 2);
const middleParentFaceY = p.y + Math.floor(FACE_HEIGHT / 2);
// Compute points for link between children and parent
let parentLinkX = didSwap
? beginSecondFaceX! + Math.floor(FACE_WIDTH / 2)
: parent_x_offset + Math.floor(memberCardWidth(pers1) / 2);
let parentLinkY = p.y;
const parentLinkY = p.y;
// Remove ugly little shifts
if (Math.abs(parentLinkX - (p.childrenLinkDestX ?? 0)) < 10)
@@ -301,7 +299,7 @@ function NodeArea(p: {
if (
pers2 &&
p.node.down.every(
(n) => n.member.father === pers1.id && n.member.mother !== pers2!.id
(n) => n.member.father === pers1.id && n.member.mother !== pers2!.id,
)
) {
childrenLinkX = parent_x_offset + Math.floor(memberCardWidth(pers1) / 2);
@@ -312,7 +310,7 @@ function NodeArea(p: {
else if (
pers2 &&
p.node.down.every(
(n) => n.member.father !== pers1.id && n.member.mother === pers2!.id
(n) => n.member.father !== pers1.id && n.member.mother === pers2!.id,
)
) {
childrenLinkX = beginSecondFaceX! + Math.floor(memberCardWidth(pers2) / 2);
@@ -371,6 +369,7 @@ function NodeArea(p: {
node={n}
/>
);
// eslint-disable-next-line react-hooks/immutability
downXOffset += n.width + SIBLINGS_SPACING;
return el;
})}
@@ -419,7 +418,7 @@ function MemberCard(p: {
<tspan
x={center(
w,
getTextWidth(p.member.lastNameUpperCase ?? "", NAME_FONT)
getTextWidth(p.member.lastNameUpperCase ?? "", NAME_FONT),
)}
dy="14"
font-size="13"
@@ -430,7 +429,7 @@ function MemberCard(p: {
<tspan
x={center(
w,
getTextWidth(p.member.displayBirthDeathShort, BIRTH_FONT)
getTextWidth(p.member.displayBirthDeathShort, BIRTH_FONT),
)}
dy="14"
font-size="10"

View File

@@ -1,3 +1,4 @@
target/
storage/
.idea
static/

2751
geneit_backend/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,38 +6,41 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4.27"
env_logger = "0.11.8"
clap = { version = "4.5.45", features = ["derive", "env"] }
log = "0.4.29"
env_logger = "0.11.10"
clap = { version = "4.6.0", features = ["derive", "env"] }
lazy_static = "1.5.0"
lazy-regex = "3.4.1"
anyhow = "1.0.99"
actix-web = "4.11.0"
lazy-regex = "3.6.0"
anyhow = "1.0.102"
actix-web = "4.13.0"
actix-cors = "0.7.1"
actix-multipart = "0.7.2"
actix-remote-ip = "0.1.0"
futures-util = "0.3.31"
diesel = { version = "2.2.12", features = ["postgres"] }
diesel_migrations = "2.2.0"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.141"
mailchecker = "6.0.17"
redis = "0.32.4"
lettre = "0.11.18"
rand = "0.9.2"
bcrypt = "0.17.1"
light-openid = "1.0.4"
thiserror = "2.0.12"
serde_with = "3.14.0"
actix-remote-ip = "1.0.0"
futures-util = "0.3.32"
diesel = { version = "2.3.7", features = ["postgres"] }
diesel_migrations = "2.3.1"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
mailchecker = "6.0.20"
redis = "1.1.0"
lettre = "0.11.20"
rand = "0.10.0"
bcrypt = "0.19.0"
light-openid = "1.1.0"
thiserror = "2.0.18"
serde_with = "3.18.0"
rust_iso3166 = "0.1.14"
rust-s3 = "0.35.1"
sha2 = "0.10.9"
image = "0.25.6"
uuid = { version = "1.17.0", features = ["v4"] }
rust-s3 = "0.37.1"
sha2 = "0.11.0"
image = "0.25.10"
uuid = { version = "1.23.0", features = ["v4"] }
httpdate = "1.0.3"
zip = "4.3.0"
zip = "8.5.0"
mime_guess = "2.0.5"
tempfile = "3.20.0"
tempfile = "3.27.0"
base64 = "0.22.1"
ical = { version = "0.11.0", features = ["generator", "ical", "vcard"] }
chrono = "0.4.41"
chrono = "0.4.44"
hex = "0.4.3"
rust-embed = { version = "8.11.0", features = ["mime-guess"] }
build-time = "0.1.3"

View File

@@ -1,10 +0,0 @@
#!/bin/bash
cargo build --release
TEMP_DIR=$(mktemp -d)
cp target/release/geneit_backend "$TEMP_DIR"
docker build -f Dockerfile "$TEMP_DIR" -t pierre42100/geneit_backend
rm -r $TEMP_DIR

View File

@@ -1,51 +1,150 @@
services:
minio:
image: minio/minio
rustfs:
image: rustfs/rustfs:1.0.0-alpha.90
user: "1000"
restart: unless-stopped
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
environment:
- MINIO_ROOT_USER=topsecret
- MINIO_ROOT_PASSWORD=topsecret
- RUSTFS_ACCESS_KEY=topsecret
- RUSTFS_SECRET_KEY=topsecret
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9090
- RUSTFS_VOLUMES=/data
volumes:
- ./storage/minio:/data
command: ["minio", "server", "/data", "--console-address", ":9090"]
- ./storage/rustfs:/data
ports:
- 9000:9000
- 9090:9090
- "9000:9000"
- "9090:9090"
expose:
- 9000
read_only: true
healthcheck:
test:
[
"CMD",
"sh", "-c",
"curl -f http://127.0.0.1:9000/health && curl -f http://127.0.0.1:9090/rustfs/console/health"
]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
image: postgres
image: postgres:18
user: "1000"
restart: unless-stopped
ports:
- "5432:5432"
expose:
- 5432
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=geneit
- PGDATA=/data
read_only: true
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U user" ]
interval: 10s
timeout: 5s
retries: 5
volumes:
- ./storage/db:/var/lib/postgresql/data
- ./storage/db:/data
tmpfs:
- /tmp
- /run/postgresql
mailcatcher:
image: dockage/mailcatcher:0.9.0
restart: unless-stopped
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
ports:
- 1080:1080
- 1025:1025
- "1080:1080"
- "1025:1025"
healthcheck:
test: wget --no-verbose --tries=1 --spider http://127.0.0.1:1080 || exit 1
interval: 5m
timeout: 3s
retries: 3
start_period: 2m
redis:
image: redis:alpine
restart: unless-stopped
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
command: redis-server --requirepass ${REDIS_PASS:-secretredis}
ports:
- 6379:6379
- "6379:6379"
healthcheck:
test: [ "CMD-SHELL", "redis-cli --no-auth-warning --pass ${REDIS_PASS:-secretredis} ping | grep PONG" ]
interval: 1s
timeout: 3s
retries: 5
volumes:
- ./storage/redis-data:/data
- ./storage/redis-conf:/usr/local/etc/redis/redis.conf
oidc:
image: qlik/simple-oidc-provider
environment:
- REDIRECTS=http://localhost:3000/oidc_cb
- PORT=9001
image: dexidp/dex
user: "1000"
restart: unless-stopped
ports:
- 9001:9001
- "9001:9001"
command: [ "dex", "serve", "/conf/dex.config.yaml" ]
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
configs:
- source: dex-config
target: /conf/dex.config.yaml
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:9001/dex/healthz || exit 1
interval: 5m
timeout: 3s
retries: 3
start_period: 2m
configs:
dex-config:
content: |
issuer: http://127.0.0.1:9001/dex
storage:
type: memory
web:
http: 0.0.0.0:9001
oauth2:
skipApprovalScreen: false
connectors:
- type: mockCallback
id: mock
name: Example
staticClients:
- id: foo
secret: bar
redirectURIs:
- http://localhost:5173/oidc_cb
name: Project

View File

@@ -1,4 +1,5 @@
use clap::Parser;
use redis::{IntoConnectionInfo, RedisConnectionInfo};
use s3::creds::Credentials;
use s3::{Bucket, Region};
@@ -11,7 +12,7 @@ pub struct AppConfig {
pub listen_address: String,
/// Website origin
#[clap(short, long, env, default_value = "http://localhost:3000")]
#[clap(short, long, env, default_value = "http://localhost:5173")]
pub website_origin: String,
/// Proxy IP, might end with a star "*"
@@ -98,7 +99,7 @@ pub struct AppConfig {
#[arg(
long,
env,
default_value = "http://localhost:9001/.well-known/openid-configuration"
default_value = "http://localhost:9001/dex/.well-known/openid-configuration"
)]
pub oidc_configuration_url: String,
@@ -188,15 +189,16 @@ impl AppConfig {
/// Get Redis connection configuration
pub fn redis_connection_config(&self) -> redis::ConnectionInfo {
redis::ConnectionInfo {
addr: redis::ConnectionAddr::Tcp(self.redis_hostname.clone(), self.redis_port),
redis: redis::RedisConnectionInfo {
db: self.redis_db_number,
username: self.redis_username.clone(),
password: Some(self.redis_password.clone()),
protocol: Default::default(),
},
let mut settings = RedisConnectionInfo::default().set_db(self.redis_db_number);
if let Some(username) = self.redis_username.as_ref() {
settings = settings.set_username(username);
}
settings = settings.set_password(&self.redis_password);
redis::ConnectionAddr::Tcp(self.redis_hostname.clone(), self.redis_port)
.into_connection_info()
.expect("could not parse redis connection info!")
.set_redis_settings(settings)
}
/// Get password reset URL

View File

@@ -34,18 +34,18 @@ impl AccommodationRequest {
}
accommodation.name = self.name;
if let Some(d) = &self.description {
if !c.accommodation_description_len.validate(d) {
if let Some(d) = &self.description
&& !c.accommodation_description_len.validate(d)
{
return Err(AccommodationListControllerErr::InvalidDescriptionLength.into());
}
}
accommodation.description.clone_from(&self.description);
if let Some(c) = &self.color {
if !lazy_regex::regex!("[a-fA-F0-9]{6}").is_match(c) {
if let Some(c) = &self.color
&& !lazy_regex::regex!("[a-fA-F0-9]{6}").is_match(c)
{
return Err(AccommodationListControllerErr::MalformedColor.into());
}
}
accommodation.color.clone_from(&self.color);
accommodation.need_validation = self.need_validation;

View File

@@ -48,23 +48,23 @@ impl CoupleRequest {
}
}
if let Some(husband) = self.husband {
if !members_service::exists(couple.family_id(), husband).await? {
if let Some(husband) = self.husband
&& !members_service::exists(couple.family_id(), husband).await?
{
return Err(CoupleControllerErr::HusbandNotExisting.into());
}
}
if let Some(d) = &self.wedding {
if !d.check() {
if let Some(d) = &self.wedding
&& !d.check()
{
return Err(CoupleControllerErr::MalformedDateOfWedding.into());
}
}
if let Some(d) = &self.divorce {
if !d.check() {
if let Some(d) = &self.divorce
&& !d.check()
{
return Err(CoupleControllerErr::MalformedDateOfDivorce.into());
}
}
couple.set_wife(self.wife);
couple.set_husband(self.husband);

View File

@@ -95,11 +95,11 @@ fn check_opt_str_val(
c: SizeConstraint,
err: MemberControllerErr,
) -> anyhow::Result<()> {
if let Some(v) = val {
if !c.validate(v) {
if let Some(v) = val
&& !c.validate(v)
{
return Err(err.into());
}
}
Ok(())
}
@@ -151,11 +151,11 @@ impl MemberRequest {
MemberControllerErr::MalformedEmailAddress,
)?;
if let Some(mail) = &self.email {
if !mailchecker::is_valid(mail) {
if let Some(mail) = &self.email
&& !mailchecker::is_valid(mail)
{
return Err(MemberControllerErr::InvalidEmailAddress.into());
}
}
check_opt_str_val(
&self.phone,
@@ -187,23 +187,23 @@ impl MemberRequest {
MemberControllerErr::MalformedCountry,
)?;
if let Some(c) = &self.country {
if !countries_utils::is_code_valid(c) {
if let Some(c) = &self.country
&& !countries_utils::is_code_valid(c)
{
return Err(MemberControllerErr::InvalidCountryCode.into());
}
}
if let Some(d) = &self.birth {
if !d.check() {
if let Some(d) = &self.birth
&& !d.check()
{
return Err(MemberControllerErr::MalformedDateOfBirth.into());
}
}
if let Some(d) = &self.death {
if !d.check() {
if let Some(d) = &self.death
&& !d.check()
{
return Err(MemberControllerErr::MalformedDateOfDeath.into());
}
}
check_opt_str_val(
&self.note,
@@ -221,11 +221,11 @@ impl MemberRequest {
}
}
if let Some(father) = self.father {
if !members_service::exists(member.family_id(), father).await? {
if let Some(father) = self.father
&& !members_service::exists(member.family_id(), father).await?
{
return Err(MemberControllerErr::FatherNotExisting.into());
}
}
member.first_name = self.first_name;
member.last_name = self.last_name;

View File

@@ -16,6 +16,7 @@ pub mod members_controller;
pub mod photos_controller;
pub mod server_controller;
pub mod users_controller;
pub mod web_app_controller;
/// Custom error to ease controller writing
#[derive(Debug)]

View File

@@ -36,16 +36,16 @@ async fn get_photo(id: &PhotoIdPath, full_size: bool, req: HttpRequest) -> HttpR
};
// Check if an upload is un-necessary
if let Some(c) = req.headers().get(header::IF_NONE_MATCH) {
if c.to_str().unwrap_or("") == hash {
if let Some(c) = req.headers().get(header::IF_NONE_MATCH)
&& c.to_str().unwrap_or("") == hash
{
return Ok(HttpResponse::NotModified().finish());
}
}
if let Some(c) = req.headers().get(header::IF_MODIFIED_SINCE) {
let date_str = c.to_str().unwrap_or("");
if let Ok(date) = httpdate::parse_http_date(date_str) {
if date
if let Ok(date) = httpdate::parse_http_date(date_str)
&& date
.add(Duration::from_secs(1))
.duration_since(UNIX_EPOCH)
.unwrap()
@@ -55,7 +55,6 @@ async fn get_photo(id: &PhotoIdPath, full_size: bool, req: HttpRequest) -> HttpR
return Ok(HttpResponse::NotModified().finish());
}
}
}
let bytes = s3_connection::get_file(&match full_size {
true => photo.photo_path(),

View File

@@ -5,11 +5,6 @@ use crate::utils::countries_utils;
use crate::utils::countries_utils::CountryCode;
use actix_web::{HttpResponse, Responder};
/// Default hello route
pub async fn home() -> impl Responder {
HttpResponse::Ok().json("GeneIT API service.")
}
#[derive(Debug, Clone, serde::Serialize)]
struct ServerConfig<'a> {
constraints: StaticConstraints,

View File

@@ -0,0 +1,75 @@
pub use serve_static::{root_index, serve_static_content};
/// Web asset hosting placeholder in debug mode
#[cfg(debug_assertions)]
mod serve_static {
use actix_web::{HttpResponse, Responder};
pub async fn root_index() -> impl Responder {
HttpResponse::Ok().body("Hello world! Debug=on for GeneIT!")
}
pub async fn serve_static_content() -> impl Responder {
HttpResponse::NotFound().body("Hello world! Static assets are not served in debug mode")
}
}
/// Web asset hosting in release mode
#[cfg(not(debug_assertions))]
mod serve_static {
use crate::utils::crypt_utils::sha256;
use crate::utils::time_utils;
use actix_web::http::header;
use actix_web::{HttpRequest, HttpResponse, Responder, web};
use rust_embed::RustEmbed;
use std::cmp::max;
use std::ops::Add;
use std::time::Duration;
#[derive(RustEmbed)]
#[folder = "static/"]
struct WebAsset;
fn handle_embedded_file(path: &str, can_fallback: bool, req: HttpRequest) -> HttpResponse {
match (WebAsset::get(path), can_fallback) {
(Some(content), _) => {
let digest = hex::encode(sha256(content.data.as_ref()));
let file_time = max(time_utils::time_start_of_day(), time_utils::build_time());
// Check if the browser already knows the file by date
if let Some(c) = req.headers().get(header::IF_MODIFIED_SINCE) {
let date_str = c.to_str().unwrap_or("");
if let Ok(date) = httpdate::parse_http_date(date_str)
&& date.add(Duration::from_secs(1))
>= time_utils::unix_to_system_time(file_time)
{
return HttpResponse::NotModified().finish();
}
}
// Check if the browser already knows the etag
if let Some(c) = req.headers().get(header::IF_NONE_MATCH)
&& c.to_str().unwrap_or("") == digest
{
return HttpResponse::NotModified().finish();
}
HttpResponse::Ok()
.content_type(content.metadata.mimetype())
.insert_header(("etag", digest))
.insert_header(("last-modified", time_utils::unix_to_http_date(file_time)))
.body(content.data.into_owned())
}
(None, false) => HttpResponse::NotFound().body("404 Not Found"),
(None, true) => handle_embedded_file("index.html", false, req),
}
}
pub async fn root_index(req: HttpRequest) -> impl Responder {
handle_embedded_file("index.html", false, req)
}
pub async fn serve_static_content(req: HttpRequest, path: web::Path<String>) -> impl Responder {
handle_embedded_file(path.as_ref(), !path.as_ref().starts_with("static/"), req)
}
}

View File

@@ -9,7 +9,7 @@ use geneit_backend::controllers::{
accommodations_list_controller, accommodations_reservations_calendars_controller,
accommodations_reservations_controller, auth_controller, couples_controller, data_controller,
families_controller, members_controller, photos_controller, server_controller,
users_controller,
users_controller, web_app_controller,
};
#[actix_web::main]
@@ -40,254 +40,259 @@ async fn main() -> std::io::Result<()> {
.max_age(3600),
)
.wrap(Logger::default())
.app_data(web::Data::new(RemoteIPConfig {
proxy: AppConfig::get().proxy_ip.clone(),
}))
.app_data(web::Data::new(RemoteIPConfig::parse_opt(
AppConfig::get().proxy_ip.clone(),
)))
// Uploaded files
.app_data(TempFileConfig::default().directory(&AppConfig::get().temp_dir))
// Config controller
.route("/", web::get().to(server_controller::home))
.route(
"/server/config",
"/api/server/config",
web::get().to(server_controller::server_config),
)
// Auth controller
.route(
"/auth/create_account",
"/api/auth/create_account",
web::post().to(auth_controller::create_account),
)
.route(
"/auth/request_reset_password",
"/api/auth/request_reset_password",
web::post().to(auth_controller::request_reset_password),
)
.route(
"/auth/check_reset_password_token",
"/api/auth/check_reset_password_token",
web::post().to(auth_controller::check_reset_password_token),
)
.route(
"/auth/reset_password",
"/api/auth/reset_password",
web::post().to(auth_controller::reset_password),
)
.route(
"/auth/password_login",
"/api/auth/password_login",
web::post().to(auth_controller::password_login),
)
.route(
"/auth/start_openid_login",
"/api/auth/start_openid_login",
web::post().to(auth_controller::start_openid_login),
)
.route(
"/auth/finish_openid_login",
"/api/auth/finish_openid_login",
web::post().to(auth_controller::finish_openid_login),
)
.route("/auth/logout", web::get().to(auth_controller::logout))
.route("/api/auth/logout", web::get().to(auth_controller::logout))
// User controller
.route("/user/info", web::get().to(users_controller::auth_info))
.route("/api/user/info", web::get().to(users_controller::auth_info))
.route(
"/user/update_profile",
"/api/user/update_profile",
web::post().to(users_controller::update_profile),
)
.route(
"/user/replace_password",
"/api/user/replace_password",
web::post().to(users_controller::replace_password),
)
.route(
"/user/request_delete",
"/api/user/request_delete",
web::get().to(users_controller::request_delete_account),
)
.route(
"/user/check_delete_token",
"/api/user/check_delete_token",
web::post().to(users_controller::check_delete_token),
)
.route(
"/user/delete_account",
"/api/user/delete_account",
web::post().to(users_controller::delete_account),
)
// Families controller
.route(
"/family/create",
"/api/family/create",
web::post().to(families_controller::create),
)
.route("/family/join", web::post().to(families_controller::join))
.route("/family/list", web::get().to(families_controller::list))
.route("/api/family/join", web::post().to(families_controller::join))
.route("/api/family/list", web::get().to(families_controller::list))
.route(
"/family/{id}",
"/api/family/{id}",
web::get().to(families_controller::single_info),
)
.route(
"/family/{id}/leave",
"/api/family/{id}/leave",
web::post().to(families_controller::leave),
)
.route("/family/{id}", web::patch().to(families_controller::update))
.route("/api/family/{id}", web::patch().to(families_controller::update))
.route(
"/family/{id}",
"/api/family/{id}",
web::delete().to(families_controller::delete),
)
.route(
"/family/{id}/renew_invitation_code",
"/api/family/{id}/renew_invitation_code",
web::post().to(families_controller::renew_invitation_code),
)
.route(
"/family/{id}/users",
"/api/family/{id}/users",
web::get().to(families_controller::users),
)
.route(
"/family/{id}/user/{user_id}",
"/api/family/{id}/user/{user_id}",
web::patch().to(families_controller::update_membership),
)
.route(
"/family/{id}/user/{user_id}",
"/api/family/{id}/user/{user_id}",
web::delete().to(families_controller::delete_membership),
)
// [GENEALOGY] Members controller
.route(
"/family/{id}/genealogy/member/create",
"/api/family/{id}/genealogy/member/create",
web::post().to(members_controller::create),
)
.route(
"/family/{id}/genealogy/members",
"/api/family/{id}/genealogy/members",
web::get().to(members_controller::get_all),
)
.route(
"/family/{id}/genealogy/member/{member_id}",
"/api/family/{id}/genealogy/member/{member_id}",
web::get().to(members_controller::get_single),
)
.route(
"/family/{id}/genealogy/member/{member_id}",
"/api/family/{id}/genealogy/member/{member_id}",
web::put().to(members_controller::update),
)
.route(
"/family/{id}/genealogy/member/{member_id}",
"/api/family/{id}/genealogy/member/{member_id}",
web::delete().to(members_controller::delete),
)
.route(
"/family/{id}/genealogy/member/{member_id}/photo",
"/api/family/{id}/genealogy/member/{member_id}/photo",
web::put().to(members_controller::set_photo),
)
.route(
"/family/{id}/genealogy/member/{member_id}/photo",
"/api/family/{id}/genealogy/member/{member_id}/photo",
web::delete().to(members_controller::remove_photo),
)
// [GENEALOGY] Couples controller
.route(
"/family/{id}/genealogy/couple/create",
"/api/family/{id}/genealogy/couple/create",
web::post().to(couples_controller::create),
)
.route(
"/family/{id}/genealogy/couples",
"/api/family/{id}/genealogy/couples",
web::get().to(couples_controller::get_all),
)
.route(
"/family/{id}/genealogy/couple/{couple_id}",
"/api/family/{id}/genealogy/couple/{couple_id}",
web::get().to(couples_controller::get_single),
)
.route(
"/family/{id}/genealogy/couple/{couple_id}",
"/api/family/{id}/genealogy/couple/{couple_id}",
web::put().to(couples_controller::update),
)
.route(
"/family/{id}/genealogy/couple/{couple_id}",
"/api/family/{id}/genealogy/couple/{couple_id}",
web::delete().to(couples_controller::delete),
)
.route(
"/family/{id}/genealogy/couple/{couple_id}/photo",
"/api/family/{id}/genealogy/couple/{couple_id}/photo",
web::put().to(couples_controller::set_photo),
)
.route(
"/family/{id}/genealogy/couple/{couple_id}/photo",
"/api/family/{id}/genealogy/couple/{couple_id}/photo",
web::delete().to(couples_controller::remove_photo),
)
// [GENEALOGY] Data controller
.route(
"/family/{id}/genealogy/data/export",
"/api/family/{id}/genealogy/data/export",
web::get().to(data_controller::export_family),
)
.route(
"/family/{id}/genealogy/data/import",
"/api/family/{id}/genealogy/data/import",
web::put().to(data_controller::import_family),
)
// [ACCOMODATIONS] List controller
.route(
"/family/{id}/accommodations/list/create",
"/api/family/{id}/accommodations/list/create",
web::post().to(accommodations_list_controller::create),
)
.route(
"/family/{id}/accommodations/list/list",
"/api/family/{id}/accommodations/list/list",
web::get().to(accommodations_list_controller::get_full_list),
)
.route(
"/family/{id}/accommodations/list/{accommodation_id}",
"/api/family/{id}/accommodations/list/{accommodation_id}",
web::get().to(accommodations_list_controller::get_single),
)
.route(
"/family/{id}/accommodations/list/{accommodation_id}",
"/api/family/{id}/accommodations/list/{accommodation_id}",
web::put().to(accommodations_list_controller::update),
)
.route(
"/family/{id}/accommodations/list/{accommodation_id}",
"/api/family/{id}/accommodations/list/{accommodation_id}",
web::delete().to(accommodations_list_controller::delete),
)
// [ACCOMODATIONS] Reservations controller
.route(
"/family/{id}/accommodations/reservations/accommodation/{accommodation_id}",
"/api/family/{id}/accommodations/reservations/accommodation/{accommodation_id}",
web::get()
.to(accommodations_reservations_controller::get_accommodation_reservations),
)
.route(
"/family/{id}/accommodations/reservations/accommodation/{accommodation_id}/for_interval",
"/api/family/{id}/accommodations/reservations/accommodation/{accommodation_id}/for_interval",
web::get()
.to(accommodations_reservations_controller::get_accommodation_reservations_for_interval),
)
.route(
"/family/{id}/accommodations/reservations/full_list",
"/api/family/{id}/accommodations/reservations/full_list",
web::get().to(accommodations_reservations_controller::full_list),
)
.route(
"/family/{id}/accommodations/reservations/accommodation/{accommodation_id}/create",
"/api/family/{id}/accommodations/reservations/accommodation/{accommodation_id}/create",
web::post().to(accommodations_reservations_controller::create_reservation),
)
.route(
"/family/{id}/accommodations/reservation/{reservation_id}",
"/api/family/{id}/accommodations/reservation/{reservation_id}",
web::get().to(accommodations_reservations_controller::get_single),
)
.route(
"/family/{id}/accommodations/reservation/{reservation_id}",
"/api/family/{id}/accommodations/reservation/{reservation_id}",
web::patch().to(accommodations_reservations_controller::update_single),
)
.route(
"/family/{id}/accommodations/reservation/{reservation_id}",
"/api/family/{id}/accommodations/reservation/{reservation_id}",
web::delete().to(accommodations_reservations_controller::delete),
)
.route(
"/family/{id}/accommodations/reservation/{reservation_id}/validate",
"/api/family/{id}/accommodations/reservation/{reservation_id}/validate",
web::post().to(accommodations_reservations_controller::validate_or_reject),
)
// [ACCOMMODATIONS] Calendars controller
.route(
"/family/{id}/accommodations/reservations_calendars/create",
"/api/family/{id}/accommodations/reservations_calendars/create",
web::post().to(accommodations_reservations_calendars_controller::create),
)
.route(
"/family/{id}/accommodations/reservations_calendars/list",
"/api/family/{id}/accommodations/reservations_calendars/list",
web::get().to(accommodations_reservations_calendars_controller::get_list),
)
.route(
"/family/{id}/accommodations/reservations_calendars/{cal_id}",
"/api/family/{id}/accommodations/reservations_calendars/{cal_id}",
web::delete().to(accommodations_reservations_calendars_controller::delete),
)
.route(
"/acccommodations_calendar/{token}",
"/api/acccommodations_calendar/{token}",
web::get().to(accommodations_reservations_calendars_controller::anonymous_access),
)
// Photos controller
.route(
"/photo/{id}",
"/api/photo/{id}",
web::get().to(photos_controller::get_full_size),
)
.route(
"/photo/{id}/thumbnail",
"/api/photo/{id}/thumbnail",
web::get().to(photos_controller::get_thumbnail),
)
// Static web app controller
.route("/", web::get().to(web_app_controller::root_index))
.route(
"/{tail:.*}",
web::get().to(web_app_controller::serve_static_content),
)
})
.bind(AppConfig::get().listen_address.as_str())?
.run()

View File

@@ -149,11 +149,11 @@ pub mod loop_detection {
impl LoopStack<'_> {
pub fn contains(&self, id: MemberID) -> bool {
if let Some(ls) = &self.prev {
if ls.contains(id) {
if let Some(ls) = &self.prev
&& ls.contains(id)
{
return true;
}
}
self.curr == id
}

View File

@@ -64,7 +64,7 @@ fn redis_key(state: &str) -> String {
format!("oidc-state-{state}")
}
async fn load_provider_info(prov_id: &str) -> anyhow::Result<OpenIDClient> {
async fn load_provider_info(prov_id: &str) -> anyhow::Result<OpenIDClient<'_>> {
let prov = AppConfig::get()
.openid_providers()
.into_iter()

View File

@@ -1,17 +1,11 @@
use sha2::{Digest, Sha256, Sha512};
/// Compute hash of a slice of bytes
pub fn sha256(bytes: &[u8]) -> String {
let mut hasher = Sha256::new();
hasher.update(bytes);
let h = hasher.finalize();
format!("{h:x}")
/// Compute SHA256sum of a given slice of bytes
pub fn sha256(input: &[u8]) -> String {
hex::encode(Sha256::digest(input))
}
/// Compute hash of a slice of bytes (sha512)
pub fn sha512(bytes: &[u8]) -> String {
let mut hasher = Sha512::new();
hasher.update(bytes);
let h = hasher.finalize();
format!("{h:x}")
/// Compute SHA512sum of a given slice of bytes
pub fn sha512(input: &[u8]) -> String {
hex::encode(Sha512::digest(input))
}

View File

@@ -1,6 +1,7 @@
//! # Time utilities
use std::time::{SystemTime, UNIX_EPOCH};
use chrono::{DateTime, Local, NaiveTime};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
/// Get the current time since epoch
pub fn time() -> u64 {
@@ -9,3 +10,29 @@ pub fn time() -> u64 {
.unwrap()
.as_secs()
}
/// Convert UNIX time to system time
pub fn unix_to_system_time(time: u64) -> SystemTime {
UNIX_EPOCH + Duration::from_secs(time)
}
/// Get build time in UNIX format
pub fn build_time() -> u64 {
let build_time = build_time::build_time_local!();
let date =
chrono::DateTime::parse_from_rfc3339(build_time).expect("Failed to parse compile date");
date.timestamp() as u64
}
/// Get the first second of the day (local time)
pub fn time_start_of_day() -> u64 {
let local: DateTime<Local> = Local::now()
.with_time(NaiveTime::from_hms_opt(0, 0, 0).unwrap())
.unwrap();
local.timestamp() as u64
}
/// Format UNIX time to HTTP date
pub fn unix_to_http_date(time: u64) -> String {
httpdate::fmt_http_date(unix_to_system_time(time))
}