From 9d135c2f25a5ff2b724e9eb23789b72142dc457f Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Fri, 13 Sep 2024 22:39:16 -0400 Subject: [PATCH 01/15] feat: initial commit for an university generic engine --- combinatoric-solver/Cargo.lock | 7 +++ combinatoric-solver/Cargo.toml | 6 +++ combinatoric-solver/src/collection.rs | 67 +++++++++++++++++++++++++++ combinatoric-solver/src/item.rs | 6 +++ combinatoric-solver/src/lib.rs | 6 +++ combinatoric-solver/src/score.rs | 1 + combinatoric-solver/src/solver.rs | 56 ++++++++++++++++++++++ 7 files changed, 149 insertions(+) create mode 100644 combinatoric-solver/Cargo.lock create mode 100644 combinatoric-solver/Cargo.toml create mode 100644 combinatoric-solver/src/collection.rs create mode 100644 combinatoric-solver/src/item.rs create mode 100644 combinatoric-solver/src/lib.rs create mode 100644 combinatoric-solver/src/score.rs create mode 100644 combinatoric-solver/src/solver.rs diff --git a/combinatoric-solver/Cargo.lock b/combinatoric-solver/Cargo.lock new file mode 100644 index 0000000..d5d26d1 --- /dev/null +++ b/combinatoric-solver/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "combinatoric-solver" +version = "0.1.0" diff --git a/combinatoric-solver/Cargo.toml b/combinatoric-solver/Cargo.toml new file mode 100644 index 0000000..cd0e860 --- /dev/null +++ b/combinatoric-solver/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "combinatoric-solver" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/combinatoric-solver/src/collection.rs b/combinatoric-solver/src/collection.rs new file mode 100644 index 0000000..f16919c --- /dev/null +++ b/combinatoric-solver/src/collection.rs @@ -0,0 +1,67 @@ +use crate::score::Score; + +#[derive(Clone)] +pub struct Collection<const MAX_ITEMS: usize, S, ItemVariant> +where + S: Score, + ItemVariant: Eq, +{ + pub score: S, + pub item_quantity: usize, + pub item_variant: [ItemVariant; MAX_ITEMS], +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> + Collection<MAX_ITEMS, S, ItemVariant> +{ + pub fn push(&self, item_variant: ItemVariant) -> Self { + let mut new = self.clone(); + new.item_variant[self.item_quantity] = item_variant; + new.item_quantity += 1; + new + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> Default + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn default() -> Self { + let score = S::default(); + let item_quantity = 0; + let item_variant = [ItemVariant::default(); MAX_ITEMS]; + Self { + score, + item_quantity, + item_variant, + } + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> PartialEq + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn eq(&self, other: &Self) -> bool { + self.item_variant == other.item_variant + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> PartialOrd + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + self.score.partial_cmp(&other.score) + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> Eq + for Collection<MAX_ITEMS, S, ItemVariant> +{ +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> Ord + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.score.cmp(&other.score) + } +} diff --git a/combinatoric-solver/src/item.rs b/combinatoric-solver/src/item.rs new file mode 100644 index 0000000..a37121c --- /dev/null +++ b/combinatoric-solver/src/item.rs @@ -0,0 +1,6 @@ +pub trait ItemVariant: Eq + Copy + Default {} + +pub trait CombinatoricItem { + type ItemVariant; + fn variants(&self) -> impl IntoIterator<Item = Self::ItemVariant>; +} diff --git a/combinatoric-solver/src/lib.rs b/combinatoric-solver/src/lib.rs new file mode 100644 index 0000000..8d79d25 --- /dev/null +++ b/combinatoric-solver/src/lib.rs @@ -0,0 +1,6 @@ +pub mod collection; +pub mod item; +pub mod score; +pub mod solver; + +pub use crate::solver::Solver; diff --git a/combinatoric-solver/src/score.rs b/combinatoric-solver/src/score.rs new file mode 100644 index 0000000..426175d --- /dev/null +++ b/combinatoric-solver/src/score.rs @@ -0,0 +1 @@ +pub trait Score: Ord + Default + Clone {} diff --git a/combinatoric-solver/src/solver.rs b/combinatoric-solver/src/solver.rs new file mode 100644 index 0000000..863a287 --- /dev/null +++ b/combinatoric-solver/src/solver.rs @@ -0,0 +1,56 @@ +use std::{cmp::Reverse, collections::BinaryHeap}; + +use crate::{ + collection::Collection, + item::{CombinatoricItem, ItemVariant}, + score::Score, +}; + +pub struct Solver<const MAX_ITEMS: usize, S, V, I, Parameters> +where + S: Score, + V: ItemVariant, + I: CombinatoricItem, +{ + top_items: BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, + max_capacity: usize, + parameters: Parameters, + items: Vec<I>, +} + +impl<'a, const MAX_ITEMS: usize, S, V, I, Parameters> Solver<MAX_ITEMS, S, V, I, Parameters> +where + S: Score, + V: ItemVariant, + I: CombinatoricItem<ItemVariant = V>, +{ + pub fn new(max_capacity: usize, items: Vec<I>, parameters: Parameters) -> Self { + let top_items = BinaryHeap::with_capacity(max_capacity); + Self { + top_items, + max_capacity, + parameters, + items, + } + } + pub fn solve(mut self) -> Vec<I> { + let item = &self.items; + Self::rec_iter(0, Collection::default(), item, &mut self.top_items); + vec![] + } + fn rec_iter( + i: usize, + collection: Collection<MAX_ITEMS, S, V>, + items: &'a [I], + top_items: &mut BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, + ) { + if i >= items.len() { + return; + } + + for variant in items[i].variants() { + let collections = collection.push(variant); + Self::rec_iter(i + 1, collections, items, top_items); + } + } +} -- GitLab From 49ccd0baccbd088e4efe04c6a7365dff553ef74f Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Fri, 13 Sep 2024 23:15:26 -0400 Subject: [PATCH 02/15] refactor: trait improvement --- combinatoric-solver/src/collection.rs | 37 +++++++++------------------ 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/combinatoric-solver/src/collection.rs b/combinatoric-solver/src/collection.rs index f16919c..a7c1dd9 100644 --- a/combinatoric-solver/src/collection.rs +++ b/combinatoric-solver/src/collection.rs @@ -1,20 +1,18 @@ -use crate::score::Score; +use crate::{item::ItemVariant, score::Score}; #[derive(Clone)] -pub struct Collection<const MAX_ITEMS: usize, S, ItemVariant> +pub struct Collection<const MAX_ITEMS: usize, S, V> where S: Score, - ItemVariant: Eq, + V: ItemVariant, { pub score: S, pub item_quantity: usize, - pub item_variant: [ItemVariant; MAX_ITEMS], + pub item_variant: [V; MAX_ITEMS], } -impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> - Collection<MAX_ITEMS, S, ItemVariant> -{ - pub fn push(&self, item_variant: ItemVariant) -> Self { +impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Collection<MAX_ITEMS, S, V> { + pub fn push(&self, item_variant: V) -> Self { let mut new = self.clone(); new.item_variant[self.item_quantity] = item_variant; new.item_quantity += 1; @@ -22,13 +20,11 @@ impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> } } -impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> Default - for Collection<MAX_ITEMS, S, ItemVariant> -{ +impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Default for Collection<MAX_ITEMS, S, V> { fn default() -> Self { let score = S::default(); let item_quantity = 0; - let item_variant = [ItemVariant::default(); MAX_ITEMS]; + let item_variant = [V::default(); MAX_ITEMS]; Self { score, item_quantity, @@ -37,30 +33,21 @@ impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> Default } } -impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> PartialEq - for Collection<MAX_ITEMS, S, ItemVariant> -{ +impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialEq for Collection<MAX_ITEMS, S, V> { fn eq(&self, other: &Self) -> bool { self.item_variant == other.item_variant } } -impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> PartialOrd - for Collection<MAX_ITEMS, S, ItemVariant> -{ +impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialOrd for Collection<MAX_ITEMS, S, V> { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { self.score.partial_cmp(&other.score) } } -impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> Eq - for Collection<MAX_ITEMS, S, ItemVariant> -{ -} +impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Eq for Collection<MAX_ITEMS, S, V> {} -impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> Ord - for Collection<MAX_ITEMS, S, ItemVariant> -{ +impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Ord for Collection<MAX_ITEMS, S, V> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.score.cmp(&other.score) } -- GitLab From 109f7106f44fa3073cebffaaafdf1cfde59d98f0 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Sat, 14 Sep 2024 21:25:31 -0400 Subject: [PATCH 03/15] refactor: simple fix --- combinatoric-solver/src/collection.rs | 13 +++++++------ combinatoric-solver/src/solver.rs | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/combinatoric-solver/src/collection.rs b/combinatoric-solver/src/collection.rs index a7c1dd9..d21d0f6 100644 --- a/combinatoric-solver/src/collection.rs +++ b/combinatoric-solver/src/collection.rs @@ -7,39 +7,39 @@ where V: ItemVariant, { pub score: S, - pub item_quantity: usize, pub item_variant: [V; MAX_ITEMS], } impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Collection<MAX_ITEMS, S, V> { - pub fn push(&self, item_variant: V) -> Self { + #[inline] + pub fn push(&self, iteration: usize, item_variant: V) -> Self { let mut new = self.clone(); - new.item_variant[self.item_quantity] = item_variant; - new.item_quantity += 1; + new.item_variant[iteration] = item_variant; new } } impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Default for Collection<MAX_ITEMS, S, V> { + #[inline] fn default() -> Self { let score = S::default(); - let item_quantity = 0; let item_variant = [V::default(); MAX_ITEMS]; Self { score, - item_quantity, item_variant, } } } impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialEq for Collection<MAX_ITEMS, S, V> { + #[inline] fn eq(&self, other: &Self) -> bool { self.item_variant == other.item_variant } } impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialOrd for Collection<MAX_ITEMS, S, V> { + #[inline] fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { self.score.partial_cmp(&other.score) } @@ -48,6 +48,7 @@ impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialOrd for Collection impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Eq for Collection<MAX_ITEMS, S, V> {} impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Ord for Collection<MAX_ITEMS, S, V> { + #[inline] fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.score.cmp(&other.score) } diff --git a/combinatoric-solver/src/solver.rs b/combinatoric-solver/src/solver.rs index 863a287..eb27c47 100644 --- a/combinatoric-solver/src/solver.rs +++ b/combinatoric-solver/src/solver.rs @@ -49,7 +49,7 @@ where } for variant in items[i].variants() { - let collections = collection.push(variant); + let collections = collection.push(i, variant); Self::rec_iter(i + 1, collections, items, top_items); } } -- GitLab From 1106c10490958ec6c66037d3cdf31924c9d96d9d Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Sat, 14 Sep 2024 22:59:41 -0400 Subject: [PATCH 04/15] refactor: continue working on item variants --- combinatoric-solver/src/collection.rs | 9 +++-- combinatoric-solver/src/lib.rs | 1 + combinatoric-solver/src/parameters.rs | 8 +++++ combinatoric-solver/src/solver.rs | 47 +++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 combinatoric-solver/src/parameters.rs diff --git a/combinatoric-solver/src/collection.rs b/combinatoric-solver/src/collection.rs index d21d0f6..831e7a8 100644 --- a/combinatoric-solver/src/collection.rs +++ b/combinatoric-solver/src/collection.rs @@ -6,17 +6,22 @@ where S: Score, V: ItemVariant, { - pub score: S, - pub item_variant: [V; MAX_ITEMS], + score: S, + item_variant: [V; MAX_ITEMS], } impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Collection<MAX_ITEMS, S, V> { #[inline] pub fn push(&self, iteration: usize, item_variant: V) -> Self { let mut new = self.clone(); + new.item_variant[iteration] = item_variant; new } + #[inline] + pub fn item_variant(&self, iteration: usize) -> &[V] { + &self.item_variant[0..iteration] + } } impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Default for Collection<MAX_ITEMS, S, V> { diff --git a/combinatoric-solver/src/lib.rs b/combinatoric-solver/src/lib.rs index 8d79d25..4d7930b 100644 --- a/combinatoric-solver/src/lib.rs +++ b/combinatoric-solver/src/lib.rs @@ -1,5 +1,6 @@ pub mod collection; pub mod item; +pub mod parameters; pub mod score; pub mod solver; diff --git a/combinatoric-solver/src/parameters.rs b/combinatoric-solver/src/parameters.rs new file mode 100644 index 0000000..2974100 --- /dev/null +++ b/combinatoric-solver/src/parameters.rs @@ -0,0 +1,8 @@ +use crate::item::ItemVariant; + +pub trait Parameters<V> +where + V: ItemVariant, +{ + fn is_valid(&self, previous_variants: &[V], new_variant: V) -> bool; +} diff --git a/combinatoric-solver/src/solver.rs b/combinatoric-solver/src/solver.rs index eb27c47..a8f47fa 100644 --- a/combinatoric-solver/src/solver.rs +++ b/combinatoric-solver/src/solver.rs @@ -1,8 +1,9 @@ -use std::{cmp::Reverse, collections::BinaryHeap}; +use std::{cmp::Reverse, collections::BinaryHeap, num::NonZeroUsize}; use crate::{ collection::Collection, item::{CombinatoricItem, ItemVariant}, + parameters::Parameters, score::Score, }; @@ -12,20 +13,22 @@ where V: ItemVariant, I: CombinatoricItem, { + /// Min-heap to keep the best schedules and fetch the worst of the best in O(1) top_items: BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, - max_capacity: usize, + max_capacity: NonZeroUsize, parameters: Parameters, items: Vec<I>, } -impl<'a, const MAX_ITEMS: usize, S, V, I, Parameters> Solver<MAX_ITEMS, S, V, I, Parameters> +impl<'a, const MAX_ITEMS: usize, S, V, I, P> Solver<MAX_ITEMS, S, V, I, P> where S: Score, V: ItemVariant, I: CombinatoricItem<ItemVariant = V>, + P: Parameters<V>, { - pub fn new(max_capacity: usize, items: Vec<I>, parameters: Parameters) -> Self { - let top_items = BinaryHeap::with_capacity(max_capacity); + pub fn new(max_capacity: NonZeroUsize, items: Vec<I>, parameters: P) -> Self { + let top_items = BinaryHeap::with_capacity(max_capacity.into()); Self { top_items, max_capacity, @@ -35,22 +38,52 @@ where } pub fn solve(mut self) -> Vec<I> { let item = &self.items; - Self::rec_iter(0, Collection::default(), item, &mut self.top_items); + Self::rec_iter( + 0, + Collection::default(), + self.max_capacity, + &self.parameters, + item, + &mut self.top_items, + ); vec![] } fn rec_iter( i: usize, collection: Collection<MAX_ITEMS, S, V>, + max_capacity: NonZeroUsize, + parameters: &P, items: &'a [I], top_items: &mut BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, ) { if i >= items.len() { + // If it reach this branch it is already valid and better than the worst top schedule, so we can push + if top_items.len() >= max_capacity.into() { + top_items.pop(); + } + top_items.push(Reverse(collection)); return; } for variant in items[i].variants() { + if !parameters.is_valid(collection.item_variant(i), variant) { + return; + } let collections = collection.push(i, variant); - Self::rec_iter(i + 1, collections, items, top_items); + // SAFETY: if the len is greater than the max_capacity, it is greater than 0 enforced by the NonZeroUsize, which allows us to unwrap without checking if it is None + if top_items.len() >= max_capacity.into() + && unsafe { top_items.peek().unwrap_unchecked().0 >= collections } + { + return; + } + Self::rec_iter( + i + 1, + collections, + max_capacity, + parameters, + items, + top_items, + ); } } } -- GitLab From 1f20f7baca02f614af2c4808f49553c004b4bdb5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Sat, 14 Sep 2024 23:42:11 -0400 Subject: [PATCH 05/15] chore: add README --- combinatoric-solver/README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 combinatoric-solver/README.md diff --git a/combinatoric-solver/README.md b/combinatoric-solver/README.md new file mode 100644 index 0000000..21c1771 --- /dev/null +++ b/combinatoric-solver/README.md @@ -0,0 +1,26 @@ +## Purpose + +This crate is a purely generic combinatoric solver. + +It allows to solve the problem of having n items to choose each with multiple variants and choosing the best combination of variants. + +A more pratical example is the original reason for writing this solver: given a list of university course that needs to be taken with multiple groups what is the top combination of group to maximise the number of day off and hours during the morning. + +## Limitation + +The algorithm explores all of the solution space for the number of combination even if it efficiently cut bad solutions. The problem is still NP-hard, so a combinatorial explosion can still happen with weak bounds and a large solution space. + +## Assumptions + +It function on the following assumptions: + +- Adding an item to the collection of item can only worsen or keep the score the same. In other words, the score function must be monotonic and decreasing. +- An invalid combination can't become valid when adding the next variant. +- The item object is really expensive to clone at lot of time, so a variant representation which is cheap to clone is used to iterate. +- Only the top N combinations are interesting. + +## How it works + +- It iterate recursively on all variants until it has a variant for each item. +- If an incomplete collection doesn't respect the constraint the rest of combination will not be explored. +- If an incomplete collection have a worst score than the worst of the best n scores, the rest of the combination of this collection will not be explored. -- GitLab From 90a0780d05361a1b55e669f83fc8f48484bdf92c Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Sat, 14 Sep 2024 23:42:54 -0400 Subject: [PATCH 06/15] chore: add name of algorithm --- combinatoric-solver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/combinatoric-solver/README.md b/combinatoric-solver/README.md index 21c1771..4da455b 100644 --- a/combinatoric-solver/README.md +++ b/combinatoric-solver/README.md @@ -23,4 +23,4 @@ It function on the following assumptions: - It iterate recursively on all variants until it has a variant for each item. - If an incomplete collection doesn't respect the constraint the rest of combination will not be explored. -- If an incomplete collection have a worst score than the worst of the best n scores, the rest of the combination of this collection will not be explored. +- If an incomplete collection have a worst score than the worst of the best n collection, the rest of the combination of this collection will not be explored. (Branch and bound) -- GitLab From 0bb6229b94c0de1298eccdc93ddc9d93ab8a6323 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Fri, 22 Nov 2024 17:23:58 -0500 Subject: [PATCH 07/15] feat: new README --- README.md | 65 ++++++++++++++++--- aep-schedule-website/Cargo.toml | 8 +-- combinatoric-solver/Cargo.lock | 7 --- combinatoric-solver/Cargo.toml | 6 -- combinatoric-solver/README.md | 26 -------- combinatoric-solver/src/collection.rs | 60 ------------------ combinatoric-solver/src/item.rs | 6 -- combinatoric-solver/src/lib.rs | 7 --- combinatoric-solver/src/parameters.rs | 8 --- combinatoric-solver/src/score.rs | 1 - combinatoric-solver/src/solver.rs | 89 --------------------------- flake.lock | 12 ++-- 12 files changed, 65 insertions(+), 230 deletions(-) delete mode 100644 combinatoric-solver/Cargo.lock delete mode 100644 combinatoric-solver/Cargo.toml delete mode 100644 combinatoric-solver/README.md delete mode 100644 combinatoric-solver/src/collection.rs delete mode 100644 combinatoric-solver/src/item.rs delete mode 100644 combinatoric-solver/src/lib.rs delete mode 100644 combinatoric-solver/src/parameters.rs delete mode 100644 combinatoric-solver/src/score.rs delete mode 100644 combinatoric-solver/src/solver.rs diff --git a/README.md b/README.md index 7fab878..86370f0 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,62 @@ -# Aep Schedule Generator Rusty +# Générateur d'horaire de l'AEP v2 -**Disclaimer** This is not yet the official AEP schedule. +## ðŸ› ï¸ Objectif du projet -## The Stack -The stack is LAC (Leptos + Axum + CSV) +Le Générateur d'horaire de l'AEP v2 est une refonte complète du générateur d'horaire étudiant, conçu pour être rapide, flexible et accessible. Ce projet modernise une base de code vieille de 15 ans et optimise l'expérience utilisateur en adoptant des technologies modernes. +## â“ FAQ -Leptos is a great frontend framework in Rust with web assembly to make a responsive UI. Axum is the fast backend serving the HTTP in Rust. The storage is done with CSV, but that's only because Poly give us CSV to represent all the courses. +### Pourquoi une refonte complète ? -## Programming Languages used to make this -- Rust +L'ancien générateur, en maintenance depuis plus de 15 ans, était obsolète avec une base de code mêlant 5 langages différents. Une refonte était essentielle pour garantir la maintenabilité et améliorer les performances. -## Credit -Marc-Antoine Manningham for the backend and the frontend +### Comment est-il aussi rapide ? -Raphael Salvas, Achille Saint-Hillier, Sunnee Chevalier and Gabriel Billard have made a figma that's the inspiration for the style \ No newline at end of file +- **Traitement local** : Les horaires sont générés directement dans le navigateur via WebAssembly, éliminant les délais liés aux serveurs. +- **Optimisation intelligente** : Seuls les meilleurs horaires sont calculés, grâce à des algorithmes comme le *branch and bound* pour réduire l'espace de recherche et respecter les contraintes définies. + +### Où puis-je soumettre des suggestions ou rapports de bugs ? + +- Utilisez le bouton **Signaler un bug** pour soumettre vos idées ou signaler un problème. +- Contributions bienvenues ! Rejoignez-nous si vous avez des compétences en Rust. + +## 👥 Crédits + +- **Développement** : Marc-Antoine Manningham (front-end & back-end) +- **Design** : Raphael Salvas, Achille Saint-Hillier, Sunnee Chevalier et Gabriel Billard, inspirés par leur maquette Figma. + + +Voici une version mise à jour du README, incluant des instructions pour l'auto-hébergement avec Docker : + +## âš™ï¸ Auto-hébergement avec Docker + +### Prérequis + +1. **Docker** : Assurez-vous que Docker est installé. [Installation Docker](https://docs.docker.com/get-docker/) +2. **Docker Compose** : (optionnel, selon votre configuration). + +### Instructions + +1. **Téléchargez et exécutez l'image Docker** : + ```bash + docker pull git.step.polymtl.ca/Lemark/aep-schedule-generator:latest + docker run -d -p 8080:8080 --name aep-schedule-generator git.step.polymtl.ca/Lemark/aep-schedule-generator:latest + ``` + +2. **Accédez à l'application** : + Ouvrez votre navigateur à l'adresse [http://localhost:8080](http://localhost:8080). + +3. **Configurer avec Docker Compose** (facultatif) : + Créez un fichier `docker-compose.yml` : + ```yaml + version: '3' + services: + aep-schedule-generator: + image: git.step.polymtl.ca/Lemark/aep-schedule-generator:latest + ports: + - "8080:8080" + ``` + Lancez les services : + ```bash + docker-compose up -d + ``` diff --git a/aep-schedule-website/Cargo.toml b/aep-schedule-website/Cargo.toml index 57f1e94..9c2731f 100644 --- a/aep-schedule-website/Cargo.toml +++ b/aep-schedule-website/Cargo.toml @@ -11,10 +11,10 @@ axum = { version = "0.7", optional = true, features = ["macros"] } console_error_panic_hook = "0.1" console_log = "1" cfg-if = "1" -leptos = { version = "0.6", features = ["nightly"] } -leptos_axum = { version = "0.6", optional = true } -leptos_meta = { version = "0.6", features = ["nightly"] } -leptos_router = { version = "0.6", features = ["nightly"] } +leptos = { version = "0.7.0-rc0", features = ["nightly"] } +leptos_axum = { version = "0.7.0-rc0", optional = true } +leptos_meta = { version = "0.7.0-rc0", features = ["nightly"] } +leptos_router = { version = "0.7.0-rc0", features = ["nightly"] } log = "0.4" rand = { version = "0.8", optional = true } simple_logger = "5" diff --git a/combinatoric-solver/Cargo.lock b/combinatoric-solver/Cargo.lock deleted file mode 100644 index d5d26d1..0000000 --- a/combinatoric-solver/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "combinatoric-solver" -version = "0.1.0" diff --git a/combinatoric-solver/Cargo.toml b/combinatoric-solver/Cargo.toml deleted file mode 100644 index cd0e860..0000000 --- a/combinatoric-solver/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "combinatoric-solver" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/combinatoric-solver/README.md b/combinatoric-solver/README.md deleted file mode 100644 index 4da455b..0000000 --- a/combinatoric-solver/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## Purpose - -This crate is a purely generic combinatoric solver. - -It allows to solve the problem of having n items to choose each with multiple variants and choosing the best combination of variants. - -A more pratical example is the original reason for writing this solver: given a list of university course that needs to be taken with multiple groups what is the top combination of group to maximise the number of day off and hours during the morning. - -## Limitation - -The algorithm explores all of the solution space for the number of combination even if it efficiently cut bad solutions. The problem is still NP-hard, so a combinatorial explosion can still happen with weak bounds and a large solution space. - -## Assumptions - -It function on the following assumptions: - -- Adding an item to the collection of item can only worsen or keep the score the same. In other words, the score function must be monotonic and decreasing. -- An invalid combination can't become valid when adding the next variant. -- The item object is really expensive to clone at lot of time, so a variant representation which is cheap to clone is used to iterate. -- Only the top N combinations are interesting. - -## How it works - -- It iterate recursively on all variants until it has a variant for each item. -- If an incomplete collection doesn't respect the constraint the rest of combination will not be explored. -- If an incomplete collection have a worst score than the worst of the best n collection, the rest of the combination of this collection will not be explored. (Branch and bound) diff --git a/combinatoric-solver/src/collection.rs b/combinatoric-solver/src/collection.rs deleted file mode 100644 index 831e7a8..0000000 --- a/combinatoric-solver/src/collection.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::{item::ItemVariant, score::Score}; - -#[derive(Clone)] -pub struct Collection<const MAX_ITEMS: usize, S, V> -where - S: Score, - V: ItemVariant, -{ - score: S, - item_variant: [V; MAX_ITEMS], -} - -impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Collection<MAX_ITEMS, S, V> { - #[inline] - pub fn push(&self, iteration: usize, item_variant: V) -> Self { - let mut new = self.clone(); - - new.item_variant[iteration] = item_variant; - new - } - #[inline] - pub fn item_variant(&self, iteration: usize) -> &[V] { - &self.item_variant[0..iteration] - } -} - -impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Default for Collection<MAX_ITEMS, S, V> { - #[inline] - fn default() -> Self { - let score = S::default(); - let item_variant = [V::default(); MAX_ITEMS]; - Self { - score, - item_variant, - } - } -} - -impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialEq for Collection<MAX_ITEMS, S, V> { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.item_variant == other.item_variant - } -} - -impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> PartialOrd for Collection<MAX_ITEMS, S, V> { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { - self.score.partial_cmp(&other.score) - } -} - -impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Eq for Collection<MAX_ITEMS, S, V> {} - -impl<const MAX_ITEMS: usize, S: Score, V: ItemVariant> Ord for Collection<MAX_ITEMS, S, V> { - #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.score.cmp(&other.score) - } -} diff --git a/combinatoric-solver/src/item.rs b/combinatoric-solver/src/item.rs deleted file mode 100644 index a37121c..0000000 --- a/combinatoric-solver/src/item.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub trait ItemVariant: Eq + Copy + Default {} - -pub trait CombinatoricItem { - type ItemVariant; - fn variants(&self) -> impl IntoIterator<Item = Self::ItemVariant>; -} diff --git a/combinatoric-solver/src/lib.rs b/combinatoric-solver/src/lib.rs deleted file mode 100644 index 4d7930b..0000000 --- a/combinatoric-solver/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod collection; -pub mod item; -pub mod parameters; -pub mod score; -pub mod solver; - -pub use crate::solver::Solver; diff --git a/combinatoric-solver/src/parameters.rs b/combinatoric-solver/src/parameters.rs deleted file mode 100644 index 2974100..0000000 --- a/combinatoric-solver/src/parameters.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::item::ItemVariant; - -pub trait Parameters<V> -where - V: ItemVariant, -{ - fn is_valid(&self, previous_variants: &[V], new_variant: V) -> bool; -} diff --git a/combinatoric-solver/src/score.rs b/combinatoric-solver/src/score.rs deleted file mode 100644 index 426175d..0000000 --- a/combinatoric-solver/src/score.rs +++ /dev/null @@ -1 +0,0 @@ -pub trait Score: Ord + Default + Clone {} diff --git a/combinatoric-solver/src/solver.rs b/combinatoric-solver/src/solver.rs deleted file mode 100644 index a8f47fa..0000000 --- a/combinatoric-solver/src/solver.rs +++ /dev/null @@ -1,89 +0,0 @@ -use std::{cmp::Reverse, collections::BinaryHeap, num::NonZeroUsize}; - -use crate::{ - collection::Collection, - item::{CombinatoricItem, ItemVariant}, - parameters::Parameters, - score::Score, -}; - -pub struct Solver<const MAX_ITEMS: usize, S, V, I, Parameters> -where - S: Score, - V: ItemVariant, - I: CombinatoricItem, -{ - /// Min-heap to keep the best schedules and fetch the worst of the best in O(1) - top_items: BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, - max_capacity: NonZeroUsize, - parameters: Parameters, - items: Vec<I>, -} - -impl<'a, const MAX_ITEMS: usize, S, V, I, P> Solver<MAX_ITEMS, S, V, I, P> -where - S: Score, - V: ItemVariant, - I: CombinatoricItem<ItemVariant = V>, - P: Parameters<V>, -{ - pub fn new(max_capacity: NonZeroUsize, items: Vec<I>, parameters: P) -> Self { - let top_items = BinaryHeap::with_capacity(max_capacity.into()); - Self { - top_items, - max_capacity, - parameters, - items, - } - } - pub fn solve(mut self) -> Vec<I> { - let item = &self.items; - Self::rec_iter( - 0, - Collection::default(), - self.max_capacity, - &self.parameters, - item, - &mut self.top_items, - ); - vec![] - } - fn rec_iter( - i: usize, - collection: Collection<MAX_ITEMS, S, V>, - max_capacity: NonZeroUsize, - parameters: &P, - items: &'a [I], - top_items: &mut BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, - ) { - if i >= items.len() { - // If it reach this branch it is already valid and better than the worst top schedule, so we can push - if top_items.len() >= max_capacity.into() { - top_items.pop(); - } - top_items.push(Reverse(collection)); - return; - } - - for variant in items[i].variants() { - if !parameters.is_valid(collection.item_variant(i), variant) { - return; - } - let collections = collection.push(i, variant); - // SAFETY: if the len is greater than the max_capacity, it is greater than 0 enforced by the NonZeroUsize, which allows us to unwrap without checking if it is None - if top_items.len() >= max_capacity.into() - && unsafe { top_items.peek().unwrap_unchecked().0 >= collections } - { - return; - } - Self::rec_iter( - i + 1, - collections, - max_capacity, - parameters, - items, - top_items, - ); - } - } -} diff --git a/flake.lock b/flake.lock index 26bce65..c662d3b 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1716137900, - "narHash": "sha256-sowPU+tLQv8GlqtVtsXioTKeaQvlMz/pefcdwg8MvfM=", + "lastModified": 1729880355, + "narHash": "sha256-RP+OQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6c0b7a92c30122196a761b440ac0d46d3d9954f1", + "rev": "18536bf04cd71abd345f9579158841376fdd0c5a", "type": "github" }, "original": { @@ -42,11 +42,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { -- GitLab From 1eef0b1afe82f9c69d923ceba078b081b12cf736 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Sat, 23 Nov 2024 15:15:49 -0500 Subject: [PATCH 08/15] feat: port everything to leptos 0.7 --- aep-schedule-website/Cargo.lock | 986 +++++++++--------- aep-schedule-website/Cargo.toml | 14 +- aep-schedule-website/src/backend/fileserv.rs | 2 +- aep-schedule-website/src/backend/routes.rs | 2 +- aep-schedule-website/src/backend/state.rs | 2 +- aep-schedule-website/src/frontend/app.rs | 101 +- .../components/common/autocomplete.rs | 8 +- .../components/common/number_input.rs | 3 +- .../frontend/components/common/schedule.rs | 6 +- .../src/frontend/components/common/tab.rs | 2 +- .../frontend/components/icons/bell_ringing.rs | 65 +- .../src/frontend/components/icons/bug.rs | 32 +- .../components/icons/calendar_check.rs | 55 +- .../frontend/components/icons/calendar_x.rs | 56 +- .../components/icons/caret_double_right.rs | 56 +- .../src/frontend/components/icons/download.rs | 62 +- .../frontend/components/icons/gitlab_logo.rs | 31 +- .../src/frontend/components/icons/house.rs | 31 +- .../frontend/components/icons/plus_circle.rs | 61 +- .../src/frontend/components/icons/sun.rs | 31 +- .../frontend/components/icons/sun_horizon.rs | 31 +- .../components/icons/warning_circle.rs | 34 +- .../src/frontend/components/icons/x.rs | 34 +- .../src/frontend/components/notifications.rs | 6 +- .../components/options/courses_selector.rs | 41 +- .../src/frontend/components/options/form.rs | 5 +- .../components/options/optimizations.rs | 10 +- .../frontend/components/options/personal.rs | 8 +- .../src/frontend/components/options/search.rs | 2 +- .../src/frontend/components/options/todo.rs | 2 +- .../src/frontend/components/schedule.rs | 62 +- .../src/frontend/components/schedules.rs | 14 +- .../src/frontend/pages/apropos.rs | 2 +- .../src/frontend/pages/classroom.rs | 20 +- .../src/frontend/pages/generator.rs | 6 +- .../src/frontend/state/mod.rs | 28 +- .../src/frontend/state/reactive_course.rs | 2 +- aep-schedule-website/src/lib.rs | 2 +- aep-schedule-website/src/main.rs | 2 +- 39 files changed, 955 insertions(+), 962 deletions(-) diff --git a/aep-schedule-website/Cargo.lock b/aep-schedule-website/Cargo.lock index 4326bf6..54b4390 100644 --- a/aep-schedule-website/Cargo.lock +++ b/aep-schedule-website/Cargo.lock @@ -54,10 +54,10 @@ dependencies = [ "reqwest", "serde", "simple_logger", - "thiserror", + "thiserror 1.0.63", "tokio", - "tower 0.5.0", - "tower-http", + "tower 0.5.1", + "tower-http 0.5.2", "tracing", "url-escape", "wasm-bindgen", @@ -145,6 +145,18 @@ dependencies = [ "libc", ] +[[package]] +name = "any_spawner" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9747eb01aed7603aba23f7c869d5d7e5d37aab9c3501aced42d8fdb786f1f6e3" +dependencies = [ + "futures", + "thiserror 1.0.63", + "tokio", + "wasm-bindgen-futures", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -177,14 +189,14 @@ dependencies = [ ] [[package]] -name = "async-recursion" -version = "1.1.1" +name = "async-lock" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.76", + "event-listener", + "event-listener-strategy", + "pin-project-lite", ] [[package]] @@ -195,7 +207,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -206,32 +218,32 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "attribute-derive" -version = "0.9.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f1ee502851995027b06f99f5ffbeffa1406b38d0b318a1ebfa469332c6cbafd" +checksum = "0053e96dd3bec5b4879c23a138d6ef26f2cb936c9cdc96274ac2b9ed44b5bb54" dependencies = [ "attribute-derive-macro", "derive-where", "manyhow", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "attribute-derive-macro" -version = "0.9.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3601467f634cfe36c4780ca9c75dea9a5b34529c1f2810676a337e7e0997f954" +checksum = "463b53ad0fd5b460af4b1915fe045ff4d946d025fb6c4dc3337752eaa980f71b" dependencies = [ "collection_literals", "interpolator", "manyhow", - "proc-macro-utils 0.8.0", + "proc-macro-utils", "proc-macro2", "quote", "quote-use", - "syn 2.0.76", + "syn", ] [[package]] @@ -242,9 +254,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.7.5" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -270,7 +282,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tower 0.4.13", + "tower 0.5.1", "tower-layer", "tower-service", "tracing", @@ -278,9 +290,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", @@ -291,7 +303,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.1", "tower-layer", "tower-service", "tracing", @@ -299,14 +311,13 @@ dependencies = [ [[package]] name = "axum-macros" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" +checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ - "heck", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -388,41 +399,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" - -[[package]] -name = "cached" -version = "0.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eb5776f28a149524d1d8623035760b4454ec881e8cf3838fa8d7e1b11254b3" -dependencies = [ - "cached_proc_macro", - "cached_proc_macro_types", - "hashbrown 0.13.2", - "instant", - "once_cell", - "thiserror", -] - -[[package]] -name = "cached_proc_macro" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cached_proc_macro_types" -version = "0.1.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "camino" @@ -479,33 +458,6 @@ dependencies = [ "stacker", ] -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "cipher" version = "0.4.4" @@ -527,6 +479,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "codee" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3ad3122b0001c7f140cf4d605ef9a9e2c24d96ab0b4fb4347b76de2425f445" +dependencies = [ + "serde", + "serde_json", + "thiserror 1.0.63", +] + [[package]] name = "collection_literals" version = "1.0.1" @@ -558,14 +521,22 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "config" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" +checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" dependencies = [ "convert_case", - "lazy_static", "nom", "pathdiff", "serde", @@ -600,24 +571,30 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] +[[package]] +name = "const_str_slice_concat" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" + [[package]] name = "constant_time_eq" version = "0.3.0" @@ -668,10 +645,10 @@ dependencies = [ ] [[package]] -name = "crunchy" -version = "0.2.2" +name = "crossbeam-utils" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-bigint" @@ -711,48 +688,14 @@ dependencies = [ "cipher", ] -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", -] - [[package]] name = "dashmap" -version = "5.5.3" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", + "crossbeam-utils", "hashbrown 0.14.5", "lock_api", "once_cell", @@ -787,7 +730,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -849,6 +792,15 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "either_of" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6e22feb4d5cacf9f2c64902a1c35ef0f2d766e42db316a98b93992bbce669cb" +dependencies = [ + "pin-project-lite", +] + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -911,6 +863,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.1.1" @@ -969,9 +942,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -984,9 +957,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -994,55 +967,56 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", "futures-util", + "num_cpus", ] [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1111,7 +1085,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -1141,6 +1115,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "guardian" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "493913a18c0d7bebb75127a26a432162c59edbe06f6cf712001e3e769345e8b5" + [[package]] name = "h2" version = "0.4.6" @@ -1160,22 +1140,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" - [[package]] name = "hashbrown" version = "0.14.5" @@ -1187,10 +1151,10 @@ dependencies = [ ] [[package]] -name = "heck" -version = "0.4.1" +name = "hashbrown" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hermit-abi" @@ -1312,11 +1276,27 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hydration_context" +version = "0.2.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e578296c79066cdf7325259d8259b48adc311e324beecd801c43d953532c51b" +dependencies = [ + "futures", + "js-sys", + "once_cell", + "or_poisoned", + "pin-project-lite", + "serde", + "throw_error", + "wasm-bindgen", +] + [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -1420,12 +1400,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.5.0" @@ -1438,12 +1412,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.1", ] [[package]] @@ -1455,15 +1429,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "interpolator" version = "0.5.0" @@ -1493,9 +1458,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -1508,9 +1473,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1537,7 +1502,7 @@ dependencies = [ "serde", "serde_json", "superboring", - "thiserror", + "thiserror 1.0.63", "zeroize", ] @@ -1566,18 +1531,35 @@ dependencies = [ [[package]] name = "leptos" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15911b4e53bb6e1b033d717eadb39924418a4a288279128122e5a65c70ba3e6" +checksum = "cc41e5764d7476efb929db94c1039752ccde5bea2ad40fddaaeeb9b94493fb0d" dependencies = [ + "any_spawner", + "base64", "cfg-if", + "either_of", + "futures", + "hydration_context", "leptos_config", "leptos_dom", + "leptos_hot_reload", "leptos_macro", - "leptos_reactive", "leptos_server", + "oco_ref", + "or_poisoned", + "paste", + "rand", + "reactive_graph", + "rustc-hash", + "send_wrapper", + "serde", + "serde_qs", "server_fn", - "tracing", + "slotmap", + "tachys", + "thiserror 2.0.3", + "throw_error", "typed-builder", "typed-builder-macro", "wasm-bindgen", @@ -1586,14 +1568,15 @@ dependencies = [ [[package]] name = "leptos_axum" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee520a923a9c93f68ca78d6b8884fc69066c6d88ce294eafa0fb9a157873bec0" +checksum = "15a7318603b14939a7332555ce8fd24a043047780dc6c9820359472ec4db6251" dependencies = [ + "any_spawner", "axum", - "cfg-if", + "dashmap", "futures", - "http-body-util", + "hydration_context", "leptos", "leptos_integration_utils", "leptos_macro", @@ -1601,61 +1584,45 @@ dependencies = [ "leptos_router", "once_cell", "parking_lot", - "serde_json", "server_fn", "tokio", - "tokio-util", - "tracing", + "tower 0.5.1", + "tower-http 0.6.2", ] [[package]] name = "leptos_config" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4d78fba18c1ccab48ffc9f3d35b39821f896b0a28bdd616a846b6241036c9" +checksum = "fe8f7f58ee40b2c0d7e1f0abdbf51ffd2343d281b3f16c1854c0218c152fbad8" dependencies = [ "config", "regex", "serde", - "thiserror", + "thiserror 2.0.3", "typed-builder", ] [[package]] name = "leptos_dom" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ccb04d4763603bb665fa35cb9642d0bd75313117d10efda9b79243c023e69df" +checksum = "3dccedefe9054b9ca09e027801557dc82cad64cb1f1a8061b114e7f6203bbe51" dependencies = [ - "async-recursion", - "cfg-if", - "drain_filter_polyfill", - "futures", - "getrandom", - "html-escape", - "indexmap", - "itertools", "js-sys", - "leptos_reactive", - "once_cell", - "pad-adapter", - "paste", - "rustc-hash", - "serde", - "serde_json", - "server_fn", - "smallvec", - "tracing", + "or_poisoned", + "reactive_graph", + "send_wrapper", + "tachys", "wasm-bindgen", - "wasm-bindgen-futures", "web-sys", ] [[package]] name = "leptos_hot_reload" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc61e5cce26761562cd3332630b3fbaddb1c4f77744e41474c7212ad279c5d9" +checksum = "754d861dbdaf20b6da328112b68e1b2ea2da9a157aef748f53b15fd118972b85" dependencies = [ "anyhow", "camino", @@ -1665,29 +1632,30 @@ dependencies = [ "quote", "rstml", "serde", - "syn 2.0.76", + "syn", "walkdir", ] [[package]] name = "leptos_integration_utils" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac080e02d0230481d80aa6920be2d634a2243f1ebbc2b8c1d57bf1bd46ca8a5b" +checksum = "30224324686ef508bc4a08fcfc16451410823b7d11b83325d2444221880bbbaa" dependencies = [ "futures", + "hydration_context", "leptos", "leptos_config", - "leptos_hot_reload", "leptos_meta", - "tracing", + "leptos_router", + "reactive_graph", ] [[package]] name = "leptos_macro" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eaea005cabb879c091c84cfec604687ececfd540469e5a30a60c93489a2f23" +checksum = "9c592d8e91148c73ee562f6d4b867d84d1995a5adb10d5a723f538b3dc173dfc" dependencies = [ "attribute-derive", "cfg-if", @@ -1696,104 +1664,85 @@ dependencies = [ "itertools", "leptos_hot_reload", "prettyplease", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "rstml", "server_fn_macro", - "syn 2.0.76", - "tracing", + "syn", "uuid", ] [[package]] name = "leptos_meta" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779bc68f8c05b15dde6557f9eb7baef4fa606a5bc450c1d6ff8787b092d0ae93" -dependencies = [ - "cfg-if", - "indexmap", - "leptos", - "tracing", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "leptos_reactive" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef2f99f377472459b0d320b46e9a9516b0e68dee5ed8c9eeb7e8eb9fefec5d2" +checksum = "7d95aec94d2c28120fe702182ec83e5402b9ad2c6fccaf3dbb98d0d94bf9f908" dependencies = [ - "base64", - "cfg-if", "futures", "indexmap", - "js-sys", - "oco_ref", - "paste", - "pin-project", - "rustc-hash", - "self_cell", - "serde", - "serde-wasm-bindgen", - "serde_json", - "slotmap", - "thiserror", - "tokio", - "tracing", + "leptos", + "once_cell", + "or_poisoned", + "send_wrapper", "wasm-bindgen", - "wasm-bindgen-futures", "web-sys", ] [[package]] name = "leptos_router" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5006e35b7c768905286dbea0d3525396cd39d961cb7b9fb664aa00b0c984ae6" +checksum = "123f2c0df5b3fd3025d1c26bc0dce1abd236409d9f031112ab5a0f871cfa6cbb" dependencies = [ - "cached", - "cfg-if", + "any_spawner", + "either_of", + "futures", "gloo-net", - "itertools", "js-sys", - "lazy_static", "leptos", - "leptos_integration_utils", - "leptos_meta", - "linear-map", - "lru", + "leptos_router_macro", "once_cell", + "or_poisoned", "percent-encoding", - "regex", + "reactive_graph", "send_wrapper", - "serde", - "serde_json", - "serde_qs 0.13.0", - "thiserror", - "tracing", + "tachys", + "thiserror 2.0.3", "url", "wasm-bindgen", - "wasm-bindgen-futures", "web-sys", ] +[[package]] +name = "leptos_router_macro" +version = "0.7.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84e0d92a7d6973682f02539b8de1f37651e72f557b1fd3f2d55460662669926" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", +] + [[package]] name = "leptos_server" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07be202a433baa8c50050de4f9c116efccffc57208bcda7bd1bb9b8e87dca9" +checksum = "a1387314dcb7f9547394a61b0cb41cdbd09e6c5dd5e154e304123f3d9b5b747b" dependencies = [ - "inventory", - "lazy_static", - "leptos_macro", - "leptos_reactive", + "any_spawner", + "base64", + "codee", + "futures", + "hydration_context", + "or_poisoned", + "reactive_graph", + "send_wrapper", "serde", + "serde_json", "server_fn", - "thiserror", - "tracing", + "tachys", ] [[package]] @@ -1841,10 +1790,6 @@ name = "linear-map" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee" -dependencies = [ - "serde", - "serde_test", -] [[package]] name = "linux-raw-sys" @@ -1868,34 +1813,25 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "lru" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" -dependencies = [ - "hashbrown 0.14.5", -] - [[package]] name = "manyhow" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91ea592d76c0b6471965708ccff7e6a5d277f676b90ab31f4d3f3fc77fade64" +checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" dependencies = [ "manyhow-macros", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "manyhow-macros" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64621e2c08f2576e4194ea8be11daf24ac01249a4f53cd8befcbb7077120ead" +checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" dependencies = [ - "proc-macro-utils 0.8.0", + "proc-macro-utils", "proc-macro2", "quote", ] @@ -1998,6 +1934,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "next_tuple" +version = "0.1.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6989c5af5a391cdc1c25aad10c6fb881b6e7ebd8df7c6fb29188acb5cba576" + [[package]] name = "nom" version = "7.1.3" @@ -2061,6 +2003,16 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_threads" version = "0.1.7" @@ -2081,19 +2033,19 @@ dependencies = [ [[package]] name = "oco_ref" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51ebcefb2f0b9a5e0bea115532c8ae4215d1b01eff176d0f4ba4192895c2708" +checksum = "64b94982fe39a861561cf67ff17a7849f2cedadbbad960a797634032b7abb998" dependencies = [ "serde", - "thiserror", + "thiserror 1.0.63", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -2124,7 +2076,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2145,6 +2097,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "or_poisoned" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd" + [[package]] name = "p256" version = "0.13.2" @@ -2170,10 +2128,10 @@ dependencies = [ ] [[package]] -name = "pad-adapter" -version = "0.1.1" +name = "parking" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d80efc4b6721e8be2a10a5df21a30fa0b470f1539e53d8b4e6e75faf938b63" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -2242,14 +2200,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -2313,12 +2271,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.21" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a909e6e8053fa1a5ad670f5816c7d93029ee1fa8898718490544a6b0d5d38b3e" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.76", + "syn", ] [[package]] @@ -2354,14 +2312,25 @@ dependencies = [ ] [[package]] -name = "proc-macro-utils" -version = "0.8.0" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ "proc-macro2", "quote", - "smallvec", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2377,9 +2346,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -2392,7 +2361,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", "version_check", "yansi", ] @@ -2431,10 +2400,10 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" dependencies = [ - "proc-macro-utils 0.10.0", + "proc-macro-utils", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2473,6 +2442,55 @@ dependencies = [ "getrandom", ] +[[package]] +name = "reactive_graph" +version = "0.1.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49131fcf9733a991f3485f9a0d0c9b9f65f55df4bb9f9d37203d1f82efa9513c" +dependencies = [ + "any_spawner", + "async-lock", + "futures", + "guardian", + "hydration_context", + "or_poisoned", + "pin-project-lite", + "rustc-hash", + "send_wrapper", + "serde", + "slotmap", + "thiserror 2.0.3", + "web-sys", +] + +[[package]] +name = "reactive_stores" +version = "0.1.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e722a72d10534f7613291bd2ef44cd2473ad70b2aa965d4bb7b940afb6f7257" +dependencies = [ + "guardian", + "itertools", + "or_poisoned", + "paste", + "reactive_graph", + "reactive_stores_macro", + "rustc-hash", +] + +[[package]] +name = "reactive_stores_macro" +version = "0.1.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b37fc52b98f16d437cdf5541cf60f661596b6e84a708e02b216a7bf864fe699b" +dependencies = [ + "convert_case", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "redox_syscall" version = "0.5.3" @@ -2484,9 +2502,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -2496,9 +2514,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -2507,9 +2525,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -2602,16 +2620,17 @@ dependencies = [ [[package]] name = "rstml" -version = "0.11.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe542870b8f59dd45ad11d382e5339c9a1047cde059be136a7016095bbdefa77" +checksum = "51187e564f12336ef40cd04f6f4d805d6919188001dcf1e0a021898ea0fe28ce" dependencies = [ + "derive-where", "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.76", + "syn", "syn_derive", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2622,9 +2641,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" @@ -2752,12 +2771,6 @@ dependencies = [ "libc", ] -[[package]] -name = "self_cell" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" - [[package]] name = "send_wrapper" version = "0.6.0" @@ -2776,17 +2789,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - [[package]] name = "serde_derive" version = "1.0.209" @@ -2795,7 +2797,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2820,17 +2822,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_qs" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" -dependencies = [ - "percent-encoding", - "serde", - "thiserror", -] - [[package]] name = "serde_qs" version = "0.13.0" @@ -2839,7 +2830,7 @@ checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6" dependencies = [ "percent-encoding", "serde", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -2851,15 +2842,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_test" -version = "1.0.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2874,13 +2856,12 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "024b400db1aca5bd4188714f7bbbf7a2e1962b9a12a80b2a21e937e509086963" +checksum = "bed94ec81d1b9ef2b28325bcf715461d861e90f41d249b70b561c6eefcb96afe" dependencies = [ "axum", "bytes", - "ciborium", "const_format", "dashmap", "futures", @@ -2891,13 +2872,15 @@ dependencies = [ "inventory", "js-sys", "once_cell", + "pin-project-lite", "send_wrapper", "serde", "serde_json", - "serde_qs 0.12.0", + "serde_qs", "server_fn_macro_default", - "thiserror", - "tower 0.4.13", + "thiserror 2.0.3", + "throw_error", + "tower 0.5.1", "tower-layer", "url", "wasm-bindgen", @@ -2909,26 +2892,26 @@ dependencies = [ [[package]] name = "server_fn_macro" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf0e6f71fc924df36e87f27dfbd447f0bedd092d365db3a5396878256d9f00c" +checksum = "4b7e77dd4f15d19a65019d24700963e40294b5a30c42c32bce2e532fbfe00b49" dependencies = [ "const_format", "convert_case", "proc-macro2", "quote", - "syn 2.0.76", + "syn", "xxhash-rust", ] [[package]] name = "server_fn_macro_default" -version = "0.6.14" +version = "0.7.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556e4fd51eb9ee3e7d9fb0febec6cef486dcbc8f7f427591dfcfebee1abe1ad4" +checksum = "295a3c3d01be1cf17d0c8b25a48b963a747f6ccdba0f62f657e8df37df4afaac" dependencies = [ "server_fn_macro", - "syn 2.0.76", + "syn", ] [[package]] @@ -2994,7 +2977,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ - "serde", "version_check", ] @@ -3049,12 +3031,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "subtle" version = "2.6.1" @@ -3076,20 +3052,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.76" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -3105,7 +3070,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -3144,6 +3109,38 @@ dependencies = [ "libc", ] +[[package]] +name = "tachys" +version = "0.1.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231b9e7ce516683c062dd2c8e4d30b81ae8d9a6d05f1e2a9c898e0b84ad728fe" +dependencies = [ + "any_spawner", + "const_str_slice_concat", + "drain_filter_polyfill", + "either_of", + "futures", + "html-escape", + "indexmap", + "itertools", + "js-sys", + "linear-map", + "next_tuple", + "oco_ref", + "once_cell", + "or_poisoned", + "parking_lot", + "paste", + "reactive_graph", + "reactive_stores", + "rustc-hash", + "send_wrapper", + "slotmap", + "throw_error", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "tempfile" version = "3.12.0" @@ -3163,7 +3160,16 @@ version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.63", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -3174,7 +3180,27 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "throw_error" +version = "0.2.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0240909e3ad4ed2dab72b2861fc9a7930110c1d3a9a0a32c6dee0a747591d10a" +dependencies = [ + "pin-project-lite", ] [[package]] @@ -3227,9 +3253,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -3251,7 +3277,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -3284,8 +3310,6 @@ dependencies = [ "bytes", "futures-core", "futures-sink", - "futures-util", - "hashbrown 0.14.5", "pin-project-lite", "tokio", ] @@ -3337,21 +3361,22 @@ dependencies = [ "tokio", "tower-layer", "tower-service", - "tracing", ] [[package]] name = "tower" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b837f86b25d7c0d7988f00a54e74739be6477f2aac6201b8f429a7569991b7" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" dependencies = [ "futures-core", "futures-util", "pin-project-lite", "sync_wrapper 0.1.2", + "tokio", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -3381,6 +3406,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -3413,7 +3463,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -3433,22 +3483,22 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typed-builder" -version = "0.18.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77739c880e00693faef3d65ea3aad725f196da38b22fdc7ea6ded6e1ce4d3add" +checksum = "7e14ed59dc8b7b26cacb2a92bad2e8b1f098806063898ab42a3bd121d7d45e75" dependencies = [ "typed-builder-macro", ] [[package]] name = "typed-builder-macro" -version = "0.18.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" +checksum = "560b82d656506509d43abe30e0ba64c56b1953ab3d4fe7ba5902747a7a3cedd5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -3543,9 +3593,9 @@ checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", "wasm-bindgen", @@ -3599,9 +3649,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -3610,24 +3660,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -3637,9 +3687,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3647,28 +3697,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -3696,9 +3746,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -3992,7 +4042,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] diff --git a/aep-schedule-website/Cargo.toml b/aep-schedule-website/Cargo.toml index 9c2731f..05af712 100644 --- a/aep-schedule-website/Cargo.toml +++ b/aep-schedule-website/Cargo.toml @@ -11,10 +11,10 @@ axum = { version = "0.7", optional = true, features = ["macros"] } console_error_panic_hook = "0.1" console_log = "1" cfg-if = "1" -leptos = { version = "0.7.0-rc0", features = ["nightly"] } -leptos_axum = { version = "0.7.0-rc0", optional = true } -leptos_meta = { version = "0.7.0-rc0", features = ["nightly"] } -leptos_router = { version = "0.7.0-rc0", features = ["nightly"] } +leptos = { version = "0.7.0-rc2", features = ["nightly"] } +leptos_router = { version = "0.7.0-rc2" } +leptos_meta = { version = "0.7.0-rc2" } +leptos_axum = { version = "0.7.0-rc2", optional = true } log = "0.4" rand = { version = "0.8", optional = true } simple_logger = "5" @@ -26,7 +26,7 @@ tower-http = { version = "0.5", features = [ "fs", ], optional = true } aep_schedule_generator = { path = "../aep-schedule-generator" } -wasm-bindgen = "=0.2.93" +wasm-bindgen = "=0.2.95" thiserror = "1.0.38" tracing = { version = "0.1.40", optional = true } serde = { version = "1.0", features = ["derive"] } @@ -50,7 +50,7 @@ lettre = { version = "0.11.7", features = [ ], optional = true } [features] -hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"] +hydrate = ["leptos/hydrate"] ssr = [ "dep:axum", "dep:tokio", @@ -60,10 +60,10 @@ ssr = [ "dep:reqwest", "dep:lettre", "dep:rand", + "dep:tracing", "leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr", - "dep:tracing", ] [profile.dev] diff --git a/aep-schedule-website/src/backend/fileserv.rs b/aep-schedule-website/src/backend/fileserv.rs index 41783dc..bde435f 100644 --- a/aep-schedule-website/src/backend/fileserv.rs +++ b/aep-schedule-website/src/backend/fileserv.rs @@ -6,7 +6,7 @@ use axum::{ response::IntoResponse, response::Response, }; -use leptos::*; +use leptos::prelude::*; use tower::ServiceExt; use tower_http::services::ServeDir; diff --git a/aep-schedule-website/src/backend/routes.rs b/aep-schedule-website/src/backend/routes.rs index 27f6ef6..0947261 100644 --- a/aep-schedule-website/src/backend/routes.rs +++ b/aep-schedule-website/src/backend/routes.rs @@ -6,7 +6,7 @@ use aep_schedule_generator::{ icalendar::calendar::Calendar, }; use compact_str::CompactString; -use leptos::*; +use leptos::prelude::*; use super::shared::user_builder::UserBuilder; diff --git a/aep-schedule-website/src/backend/state.rs b/aep-schedule-website/src/backend/state.rs index 453eb8c..1379dc7 100644 --- a/aep-schedule-website/src/backend/state.rs +++ b/aep-schedule-website/src/backend/state.rs @@ -8,7 +8,7 @@ use axum::{ http::Request, response::{IntoResponse, Response}, }; -use leptos::*; +use leptos::prelude::*; use leptos_axum::handle_server_fns_with_context; use leptos_router::RouteListing; use std::fs::File; diff --git a/aep-schedule-website/src/frontend/app.rs b/aep-schedule-website/src/frontend/app.rs index c53b5bf..d0bbb14 100644 --- a/aep-schedule-website/src/frontend/app.rs +++ b/aep-schedule-website/src/frontend/app.rs @@ -4,17 +4,68 @@ use crate::frontend::components::icons::IconWeight; use crate::frontend::pages::apropos::HomePage; use crate::frontend::pages::classroom::ClassRoomComponent; use crate::frontend::pages::generator::GeneratorPage; -use leptos::*; +use leptos::prelude::*; use leptos_meta::*; -use leptos_router::*; +use leptos_router::{ + components::{FlatRoutes, Route, Router, A}, + StaticSegment, +}; + +pub fn shell(options: LeptosOptions) -> impl IntoView { + view! { + <!DOCTYPE html> + <html lang="en"> + <head> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1"/> + <AutoReload options=options.clone() /> + <HydrationScripts options/> + <MetaTags/> + </head> + <body> + <App/> + </body> + </html> + } +} #[component] -pub fn App() -> impl IntoView { - // Provides context that manages stylesheets, titles, meta tags, etc. - provide_meta_context(); +pub fn Nav() -> impl IntoView { + let (is_active, set_active) = signal(false); + + view! { + <header> + <nav class=("active", is_active) class="flex-wrap overflow-x-hidden"> + <span class="text-2xl font-semibold leading-none font-sans tracking-tight">"Générateur d'horaire de l'AEP" + <span class="text-amber-600">"v2"</span> + </span> + <span class="bg-red-200 text-red-800 text-lg font-sans tracking-tight font-medium me-2 px-2.5 py-0.5 rounded-full shrink">"Beta - "<a class="text-gray-800" href="https://horaires.aep.polymtl.ca/">"Retourner à l'ancien générateur"</a></span> + <A href="/"><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Générateur d'horaire"</span></A> + <A href="/local"><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Horaire d'un local"</span></A> + <A href="/apropos"><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"À propos"</span></A> - let (is_active, set_active) = create_signal(false); + <a href="https://forms.gle/u5AWgGx7vcLbCPCc7" class="sources pad-left" target="_blank"> + <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Signaler un bug"</span> + <Bug weight=IconWeight::Regular size="3vh"/> + </a> + <a href="https://git.step.polymtl.ca/Lemark/aep-schedule-generator-rusty" class="sources" target="_blank" ><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Sources "</span><GitlabLogo weight=IconWeight::Regular size="3vh"/></a> + </nav> + <div class=("active", is_active) class="hamburger" on:pointerdown=move |_| { + set_active.update(|active| { + *active = !*active; + }); + }> + <span class="hamburger-bar"></span> + <span class="hamburger-bar"></span> + <span class="hamburger-bar"></span> + </div> + </header> + } +} + +#[component] +pub fn App() -> impl IntoView { view! { // injects a stylesheet into the document <head> @@ -26,39 +77,13 @@ pub fn App() -> impl IntoView { // content for this welcome page <Router> - <header> - <nav class=("active", is_active) class="flex-wrap overflow-x-hidden"> - <span class="text-2xl font-semibold leading-none font-sans tracking-tight">"Générateur d'horaire de l'AEP" - <span class="text-amber-600">"v2"</span> - </span> - <span class="bg-red-200 text-red-800 text-lg font-sans tracking-tight font-medium me-2 px-2.5 py-0.5 rounded-full shrink">"Beta - "<a class="text-gray-800" href="https://horaires.aep.polymtl.ca/">"Retourner à l'ancien générateur"</a></span> - <A class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight" href="/">"Générateur d'horaire"</A> - <A class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight" href="/local">"Horaire d'un local"</A> - <A class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight" href="/apropos">"À propos"</A> - - - <a href="https://forms.gle/u5AWgGx7vcLbCPCc7" class="sources pad-left" target="_blank"> - <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Signaler un bug"</span> - <Bug weight=IconWeight::Regular size="3vh"/> - </a> - <a href="https://git.step.polymtl.ca/Lemark/aep-schedule-generator-rusty" class="sources" target="_blank" ><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Sources "</span><GitlabLogo weight=IconWeight::Regular size="3vh"/></a> - </nav> - <div class=("active", is_active) class="hamburger" on:pointerdown=move |_| { - set_active.update(|active| { - *active = !*active; - }); - }> - <span class="hamburger-bar"></span> - <span class="hamburger-bar"></span> - <span class="hamburger-bar"></span> - </div> - </header> + <Nav/> <main class="h-full"> - <Routes> - <Route path="/" view=GeneratorPage/> - <Route path="/apropos" view=HomePage/> - <Route path="/local" view=ClassRoomComponent/> - </Routes> + <FlatRoutes fallback=|| "Not found"> + <Route path=StaticSegment("/") view=GeneratorPage/> + <Route path=StaticSegment("/apropos") view=HomePage/> + <Route path=StaticSegment("/local") view=ClassRoomComponent/> + </FlatRoutes> </main> </Router> } diff --git a/aep-schedule-website/src/frontend/components/common/autocomplete.rs b/aep-schedule-website/src/frontend/components/common/autocomplete.rs index 4e1bf07..816bb1b 100644 --- a/aep-schedule-website/src/frontend/components/common/autocomplete.rs +++ b/aep-schedule-website/src/frontend/components/common/autocomplete.rs @@ -1,5 +1,5 @@ use crate::frontend::components::icons::plus_circle::PlusCircle; -use leptos::*; +use leptos::prelude::*; use std::{cmp, ops::Range}; #[derive(Clone, PartialEq)] @@ -42,10 +42,10 @@ pub fn AutoComplete<F: FnMut(String) + Copy + Clone + 'static>( id: &'static str, mut submit: F, ) -> impl IntoView { - let input = create_rw_signal(String::new()); - let (suggestion_range, set_suggestion_range) = create_signal(0..0); + let input = RwSignal::new(String::new()); + let (suggestion_range, set_suggestion_range) = signal(0..0); let suggestions = suggestion_list.clone(); - let is_hidden = create_rw_signal(true); + let is_hidden = RwSignal::new(true); let on_input = move |ev| { let value = event_target_value(&ev); diff --git a/aep-schedule-website/src/frontend/components/common/number_input.rs b/aep-schedule-website/src/frontend/components/common/number_input.rs index 5dc3e45..c5ded8d 100644 --- a/aep-schedule-website/src/frontend/components/common/number_input.rs +++ b/aep-schedule-website/src/frontend/components/common/number_input.rs @@ -1,4 +1,4 @@ -use leptos::*; +use leptos::prelude::*; #[component] pub fn NumberInput<F>( @@ -46,7 +46,6 @@ where class="bg-gray-50 border-x-0 border-gray-300 h-7 text-center text-gray-900 text-sm focus:ring-amber-500 focus:border-amber-500 block w-full py-2.5" placeholder="0" on:input=on_input - type="number" min="0" max=max prop:value=value diff --git a/aep-schedule-website/src/frontend/components/common/schedule.rs b/aep-schedule-website/src/frontend/components/common/schedule.rs index 94deb8b..94a2380 100644 --- a/aep-schedule-website/src/frontend/components/common/schedule.rs +++ b/aep-schedule-website/src/frontend/components/common/schedule.rs @@ -1,5 +1,5 @@ use aep_schedule_generator::data::time::period::Period; -use leptos::*; +use leptos::prelude::*; use std::array; #[component] @@ -38,8 +38,8 @@ pub fn Schedule( } #[component] -pub fn ScheduleEvent<'a>( - period: &'a Period, +pub fn ScheduleEvent( + period: Period, children: Children, #[prop(optional)] class: String, ) -> impl IntoView { diff --git a/aep-schedule-website/src/frontend/components/common/tab.rs b/aep-schedule-website/src/frontend/components/common/tab.rs index e330d3b..6993eee 100644 --- a/aep-schedule-website/src/frontend/components/common/tab.rs +++ b/aep-schedule-website/src/frontend/components/common/tab.rs @@ -1,4 +1,4 @@ -use leptos::*; +use leptos::prelude::*; #[component] pub fn Tab(active_tab: ReadSignal<String>, tab_id: String, children: Children) -> impl IntoView { diff --git a/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs b/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs index 8d7dc68..9ec0b79 100644 --- a/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs +++ b/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs @@ -1,47 +1,41 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn BellRinging( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + weight: Signal<IconWeight>, + size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { + let body = move || { match weight.get() { - IconWeight::Fill => view! { - <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0Z"></path> - }.into_view(), -IconWeight::Duotone => view! { - <path - d="M208,192H48a8,8,0,0,1-6.88-12C47.71,168.6,56,147.81,56,112a72,72,0,0,1,144,0c0,35.82,8.3,56.6,14.9,68A8,8,0,0,1,208,192Z" - opacity="0.2" - ></path> - <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> -}.into_view(), -IconWeight::Thin => view! { - <path d="M222.13,67.55a3.94,3.94,0,0,1-1.84.45,4,4,0,0,1-3.55-2.16,99.41,99.41,0,0,0-34.87-38.46,4,4,0,1,1,4.26-6.76,107.34,107.34,0,0,1,37.71,41.54A4,4,0,0,1,222.13,67.55ZM39.26,65.84A99.41,99.41,0,0,1,74.13,27.38a4,4,0,0,0-4.26-6.76A107.34,107.34,0,0,0,32.16,62.16a4,4,0,0,0,1.71,5.39,3.94,3.94,0,0,0,1.84.45A4,4,0,0,0,39.26,65.84ZM218.36,178A12,12,0,0,1,208,196H163.77a36,36,0,0,1-71.54,0H48A12,12,0,0,1,37.64,178C47.17,161.56,52,139.37,52,112a76,76,0,0,1,152,0C204,139.36,208.83,161.55,218.36,178ZM155.71,196H100.29a28,28,0,0,0,55.42,0Zm55.73-14C201.19,164.34,196,140.79,196,112a68,68,0,0,0-136,0c0,28.8-5.19,52.34-15.44,70a4,4,0,0,0,0,4A3.89,3.89,0,0,0,48,188H208a3.89,3.89,0,0,0,3.43-2A4,4,0,0,0,211.44,182Z"></path> -}.into_view(), -IconWeight::Bold => view! { - <path d="M225.81,74.65A11.86,11.86,0,0,1,220.3,76a12,12,0,0,1-10.67-6.47,90.1,90.1,0,0,0-32-35.38,12,12,0,1,1,12.8-20.29,115.25,115.25,0,0,1,40.54,44.62A12,12,0,0,1,225.81,74.65ZM46.37,69.53a90.1,90.1,0,0,1,32-35.38A12,12,0,1,0,65.6,13.86,115.25,115.25,0,0,0,25.06,58.48a12,12,0,0,0,5.13,16.17A11.86,11.86,0,0,0,35.7,76,12,12,0,0,0,46.37,69.53Zm173.51,98.35A20,20,0,0,1,204,200H171.81a44,44,0,0,1-87.62,0H52a20,20,0,0,1-15.91-32.12c7.17-9.33,15.73-26.62,15.88-55.94A76,76,0,0,1,204,112C204.15,141.26,212.71,158.55,219.88,167.88ZM147.6,200H108.4a20,20,0,0,0,39.2,0Zm48.74-24c-8.16-13-16.19-33.57-16.34-63.94A52,52,0,1,0,76,112c-.15,30.42-8.18,51-16.34,64Z"></path> -}.into_view(), -IconWeight::Light => view! { - <path d="M223.05,69.33A6,6,0,0,1,215,66.76,96,96,0,0,0,180.8,29.08a6,6,0,0,1,6.4-10.15,109.26,109.26,0,0,1,38.41,42.31A6,6,0,0,1,223.05,69.33ZM41,66.76A96,96,0,0,1,75.2,29.08a6,6,0,0,0-6.4-10.15A109.26,109.26,0,0,0,30.39,61.24,6,6,0,1,0,41,66.76Zm179,110.18A14,14,0,0,1,208,198h-42.5a38,38,0,0,1-75,0H48a14,14,0,0,1-12.06-21.06C45.13,161.09,50,138.63,50,112a78,78,0,0,1,156,0C206,139,210.74,160.86,220.08,176.94ZM153.29,198H102.71a26,26,0,0,0,50.58,0Zm56.42-15C199.29,165,194,141.15,194,112a66,66,0,0,0-132,0c0,29.16-5.29,53-15.71,71a2,2,0,0,0,0,2,1.9,1.9,0,0,0,1.7,1H208a1.9,1.9,0,0,0,1.7-1A2,2,0,0,0,209.71,183Z"></path> -}.into_view(), -IconWeight::Regular => view! { - <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> -}.into_view() - } - }); + IconWeight::Fill => view! { + <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0Z"></path> + }.into_any(), + IconWeight::Duotone => view! { + <path + d="M208,192H48a8,8,0,0,1-6.88-12C47.71,168.6,56,147.81,56,112a72,72,0,0,1,144,0c0,35.82,8.3,56.6,14.9,68A8,8,0,0,1,208,192Z" + opacity="0.2" + ></path> + <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> + }.into_any(), + IconWeight::Thin => view! { + <path d="M222.13,67.55a3.94,3.94,0,0,1-1.84.45,4,4,0,0,1-3.55-2.16,99.41,99.41,0,0,0-34.87-38.46,4,4,0,1,1,4.26-6.76,107.34,107.34,0,0,1,37.71,41.54A4,4,0,0,1,222.13,67.55ZM39.26,65.84A99.41,99.41,0,0,1,74.13,27.38a4,4,0,0,0-4.26-6.76A107.34,107.34,0,0,0,32.16,62.16a4,4,0,0,0,1.71,5.39,3.94,3.94,0,0,0,1.84.45A4,4,0,0,0,39.26,65.84ZM218.36,178A12,12,0,0,1,208,196H163.77a36,36,0,0,1-71.54,0H48A12,12,0,0,1,37.64,178C47.17,161.56,52,139.37,52,112a76,76,0,0,1,152,0C204,139.36,208.83,161.55,218.36,178ZM155.71,196H100.29a28,28,0,0,0,55.42,0Zm55.73-14C201.19,164.34,196,140.79,196,112a68,68,0,0,0-136,0c0,28.8-5.19,52.34-15.44,70a4,4,0,0,0,0,4A3.89,3.89,0,0,0,48,188H208a3.89,3.89,0,0,0,3.43-2A4,4,0,0,0,211.44,182Z"></path> + }.into_any(), + IconWeight::Bold => view! { + <path d="M225.81,74.65A11.86,11.86,0,0,1,220.3,76a12,12,0,0,1-10.67-6.47,90.1,90.1,0,0,0-32-35.38,12,12,0,1,1,12.8-20.29,115.25,115.25,0,0,1,40.54,44.62A12,12,0,0,1,225.81,74.65ZM46.37,69.53a90.1,90.1,0,0,1,32-35.38A12,12,0,1,0,65.6,13.86,115.25,115.25,0,0,0,25.06,58.48a12,12,0,0,0,5.13,16.17A11.86,11.86,0,0,0,35.7,76,12,12,0,0,0,46.37,69.53Zm173.51,98.35A20,20,0,0,1,204,200H171.81a44,44,0,0,1-87.62,0H52a20,20,0,0,1-15.91-32.12c7.17-9.33,15.73-26.62,15.88-55.94A76,76,0,0,1,204,112C204.15,141.26,212.71,158.55,219.88,167.88ZM147.6,200H108.4a20,20,0,0,0,39.2,0Zm48.74-24c-8.16-13-16.19-33.57-16.34-63.94A52,52,0,1,0,76,112c-.15,30.42-8.18,51-16.34,64Z"></path> + }.into_any(), + IconWeight::Light => view! { + <path d="M223.05,69.33A6,6,0,0,1,215,66.76,96,96,0,0,0,180.8,29.08a6,6,0,0,1,6.4-10.15,109.26,109.26,0,0,1,38.41,42.31A6,6,0,0,1,223.05,69.33ZM41,66.76A96,96,0,0,1,75.2,29.08a6,6,0,0,0-6.4-10.15A109.26,109.26,0,0,0,30.39,61.24,6,6,0,1,0,41,66.76Zm179,110.18A14,14,0,0,1,208,198h-42.5a38,38,0,0,1-75,0H48a14,14,0,0,1-12.06-21.06C45.13,161.09,50,138.63,50,112a78,78,0,0,1,156,0C206,139,210.74,160.86,220.08,176.94ZM153.29,198H102.71a26,26,0,0,0,50.58,0Zm56.42-15C199.29,165,194,141.15,194,112a66,66,0,0,0-132,0c0,29.16-5.29,53-15.71,71a2,2,0,0,0,0,2,1.9,1.9,0,0,0,1.7,1H208a1.9,1.9,0,0,0,1.7-1A2,2,0,0,0,209.71,183Z"></path> + }.into_any(), + IconWeight::Regular => view! { + <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> + }.into_any() + } + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -49,8 +43,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/bug.rs b/aep-schedule-website/src/frontend/components/icons/bug.rs index daafa57..123ec96 100644 --- a/aep-schedule-website/src/frontend/components/icons/bug.rs +++ b/aep-schedule-website/src/frontend/components/icons/bug.rs @@ -1,43 +1,38 @@ -//! GENERATED FILE use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn Bug( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: IconWeight, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = move || { + match weight { IconWeight::Fill => view! { <path d="M168,92a12,12,0,1,1-12-12A12,12,0,0,1,168,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216Zm-80,0a8,8,0,0,0-16,0v64a8,8,0,0,0,16,0Zm64-32a72,72,0,0,0-144,0v8H200Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M208,128v16a80,80,0,0,1-160,0V128Z" opacity="0.2"></path> <path d="M144,92a12,12,0,1,1,12,12A12,12,0,0,1,144,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216ZM56,120H200v-8a72,72,0,0,0-144,0Zm64,95.54V136H56v8A72.08,72.08,0,0,0,120,215.54ZM200,144v-8H136v79.54A72.08,72.08,0,0,0,200,144Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M148,92a8,8,0,1,1,8,8A8,8,0,0,1,148,92Zm-48-8a8,8,0,1,0,8,8A8,8,0,0,0,100,84Zm144,44a4,4,0,0,1-4,4H212v12a83.64,83.64,0,0,1-3.87,25.2l25.47,11.13A4,4,0,0,1,232,188a4.09,4.09,0,0,1-1.6-.33l-25-10.95a84,84,0,0,1-154.72,0l-25,10.95A4.09,4.09,0,0,1,24,188a4,4,0,0,1-1.6-7.67L47.87,169.2A83.64,83.64,0,0,1,44,144V132H16a4,4,0,0,1,0-8H44V112a83.64,83.64,0,0,1,3.87-25.2L22.4,75.67a4,4,0,0,1,3.2-7.34l25,11a84,84,0,0,1,154.72,0l25-11a4,4,0,1,1,3.2,7.34L208.13,86.8A83.64,83.64,0,0,1,212,112v12h28A4,4,0,0,1,244,128ZM52,124H204V112a76,76,0,0,0-152,0Zm72,95.89V132H52v12A76.09,76.09,0,0,0,124,219.89ZM204,132H132v87.89A76.09,76.09,0,0,0,204,144Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M140,88a16,16,0,1,1,16,16A16,16,0,0,1,140,88ZM100,72a16,16,0,1,0,16,16A16,16,0,0,0,100,72Zm120,72a91.84,91.84,0,0,1-2.34,20.64L236.81,173a12,12,0,0,1-9.62,22l-18-7.85a92,92,0,0,1-162.46,0l-18,7.85a12,12,0,1,1-9.62-22l19.15-8.36A91.84,91.84,0,0,1,36,144v-4H16a12,12,0,0,1,0-24H36v-4a91.84,91.84,0,0,1,2.34-20.64L19.19,83a12,12,0,0,1,9.62-22l18,7.85a92,92,0,0,1,162.46,0l18-7.85a12,12,0,1,1,9.62,22l-19.15,8.36A91.84,91.84,0,0,1,220,112v4h20a12,12,0,0,1,0,24H220ZM60,116H196v-4a68,68,0,0,0-136,0Zm56,94.92V140H60v4A68.1,68.1,0,0,0,116,210.92ZM196,144v-4H140v70.92A68.1,68.1,0,0,0,196,144Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M146,92a10,10,0,1,1,10,10A10,10,0,0,1,146,92ZM100,82a10,10,0,1,0,10,10A10,10,0,0,0,100,82Zm146,46a6,6,0,0,1-6,6H214v10a85.88,85.88,0,0,1-3.45,24.08L234.4,178.5a6,6,0,0,1-4.8,11l-23.23-10.15a86,86,0,0,1-156.74,0L26.4,189.5a6,6,0,1,1-4.8-11l23.85-10.42A85.88,85.88,0,0,1,42,144V134H16a6,6,0,0,1,0-12H42V112a85.88,85.88,0,0,1,3.45-24.08L21.6,77.5a6,6,0,0,1,4.8-11L49.63,76.65a86,86,0,0,1,156.74,0L229.6,66.5a6,6,0,1,1,4.8,11L210.55,87.92A85.88,85.88,0,0,1,214,112v10h26A6,6,0,0,1,246,128ZM54,122H202V112a74,74,0,0,0-148,0Zm68,95.74V134H54v10A74.09,74.09,0,0,0,122,217.74ZM202,134H134v83.74A74.09,74.09,0,0,0,202,144Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M144,92a12,12,0,1,1,12,12A12,12,0,0,1,144,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216ZM56,120H200v-8a72,72,0,0,0-144,0Zm64,95.54V136H56v8A72.08,72.08,0,0,0,120,215.54ZM200,144v-8H136v79.54A72.08,72.08,0,0,0,200,144Z"></path> -}.into_view() +}.into_any() } - }); + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -45,8 +40,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/calendar_check.rs b/aep-schedule-website/src/frontend/components/icons/calendar_check.rs index 3ce85ad..939e21a 100644 --- a/aep-schedule-website/src/frontend/components/icons/calendar_check.rs +++ b/aep-schedule-website/src/frontend/components/icons/calendar_check.rs @@ -1,44 +1,38 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn CalendarCheck( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: Signal<IconWeight>, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { + let body = move || { match weight.get() { IconWeight::Fill => view! { <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM169.66,133.66l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35a8,8,0,0,1,11.32,11.32ZM48,80V48H72v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80Z"></path> - }.into_view(), -IconWeight::Duotone => view! { - <path d="M216,48V88H40V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z" opacity="0.2"></path> - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> -}.into_view(), -IconWeight::Thin => view! { - <path d="M208,36H180V24a4,4,0,0,0-8,0V36H84V24a4,4,0,0,0-8,0V36H48A12,12,0,0,0,36,48V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V48A12,12,0,0,0,208,36ZM48,44H76V56a4,4,0,0,0,8,0V44h88V56a4,4,0,0,0,8,0V44h28a4,4,0,0,1,4,4V84H44V48A4,4,0,0,1,48,44ZM208,212H48a4,4,0,0,1-4-4V92H212V208A4,4,0,0,1,208,212Zm-41.17-86.83a4,4,0,0,1,0,5.66l-48,48a4,4,0,0,1-5.66,0l-24-24a4,4,0,0,1,5.66-5.66L116,170.34l45.17-45.17A4,4,0,0,1,166.83,125.17Z"></path> -}.into_view(), -IconWeight::Bold => view! { - <path d="M208,28H188V24a12,12,0,0,0-24,0v4H92V24a12,12,0,0,0-24,0v4H48A20,20,0,0,0,28,48V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V48A20,20,0,0,0,208,28ZM68,52a12,12,0,0,0,24,0h72a12,12,0,0,0,24,0h16V76H52V52ZM52,204V100H204V204Zm120.49-84.49a12,12,0,0,1,0,17l-48,48a12,12,0,0,1-17,0l-24-24a12,12,0,0,1,17-17L116,159l39.51-39.52A12,12,0,0,1,172.49,119.51Z"></path> -}.into_view(), -IconWeight::Light => view! { - <path d="M208,34H182V24a6,6,0,0,0-12,0V34H86V24a6,6,0,0,0-12,0V34H48A14,14,0,0,0,34,48V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V48A14,14,0,0,0,208,34ZM48,46H74V56a6,6,0,0,0,12,0V46h84V56a6,6,0,0,0,12,0V46h26a2,2,0,0,1,2,2V82H46V48A2,2,0,0,1,48,46ZM208,210H48a2,2,0,0,1-2-2V94H210V208A2,2,0,0,1,208,210Zm-39.76-86.24a6,6,0,0,1,0,8.48l-48,48a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L116,167.51l43.76-43.75A6,6,0,0,1,168.24,123.76Z"></path> -}.into_view(), -IconWeight::Regular => view! { - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> -}.into_view() - } - }); + }.into_any(), + IconWeight::Duotone => view! { + <path d="M216,48V88H40V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z" opacity="0.2"></path> + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> + }.into_any(), + IconWeight::Thin => view! { + <path d="M208,36H180V24a4,4,0,0,0-8,0V36H84V24a4,4,0,0,0-8,0V36H48A12,12,0,0,0,36,48V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V48A12,12,0,0,0,208,36ZM48,44H76V56a4,4,0,0,0,8,0V44h88V56a4,4,0,0,0,8,0V44h28a4,4,0,0,1,4,4V84H44V48A4,4,0,0,1,48,44ZM208,212H48a4,4,0,0,1-4-4V92H212V208A4,4,0,0,1,208,212Zm-41.17-86.83a4,4,0,0,1,0,5.66l-48,48a4,4,0,0,1-5.66,0l-24-24a4,4,0,0,1,5.66-5.66L116,170.34l45.17-45.17A4,4,0,0,1,166.83,125.17Z"></path> + }.into_any(), + IconWeight::Bold => view! { + <path d="M208,28H188V24a12,12,0,0,0-24,0v4H92V24a12,12,0,0,0-24,0v4H48A20,20,0,0,0,28,48V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V48A20,20,0,0,0,208,28ZM68,52a12,12,0,0,0,24,0h72a12,12,0,0,0,24,0h16V76H52V52ZM52,204V100H204V204Zm120.49-84.49a12,12,0,0,1,0,17l-48,48a12,12,0,0,1-17,0l-24-24a12,12,0,0,1,17-17L116,159l39.51-39.52A12,12,0,0,1,172.49,119.51Z"></path> + }.into_any(), + IconWeight::Light => view! { + <path d="M208,34H182V24a6,6,0,0,0-12,0V34H86V24a6,6,0,0,0-12,0V34H48A14,14,0,0,0,34,48V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V48A14,14,0,0,0,208,34ZM48,46H74V56a6,6,0,0,0,12,0V46h84V56a6,6,0,0,0,12,0V46h26a2,2,0,0,1,2,2V82H46V48A2,2,0,0,1,48,46ZM208,210H48a2,2,0,0,1-2-2V94H210V208A2,2,0,0,1,208,210Zm-39.76-86.24a6,6,0,0,1,0,8.48l-48,48a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L116,167.51l43.76-43.75A6,6,0,0,1,168.24,123.76Z"></path> + }.into_any(), + IconWeight::Regular => view! { + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> + }.into_any() + } + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -46,8 +40,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/calendar_x.rs b/aep-schedule-website/src/frontend/components/icons/calendar_x.rs index c2d86ea..f431dc7 100644 --- a/aep-schedule-website/src/frontend/components/icons/calendar_x.rs +++ b/aep-schedule-website/src/frontend/components/icons/calendar_x.rs @@ -1,44 +1,37 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn CalendarX( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: IconWeight, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = + match weight { IconWeight::Fill => view! { <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM157.66,170.34a8,8,0,0,1-11.32,11.32L128,163.31l-18.34,18.35a8,8,0,0,1-11.32-11.32L116.69,152,98.34,133.66a8,8,0,0,1,11.32-11.32L128,140.69l18.34-18.35a8,8,0,0,1,11.32,11.32L139.31,152ZM208,80H48V48H72v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24Z"></path> - }.into_view(), -IconWeight::Duotone => view! { - <path d="M216,48V88H40V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z" opacity="0.2"></path> - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-50.34-74.34L139.31,152l18.35,18.34a8,8,0,0,1-11.32,11.32L128,163.31l-18.34,18.35a8,8,0,0,1-11.32-11.32L116.69,152,98.34,133.66a8,8,0,0,1,11.32-11.32L128,140.69l18.34-18.35a8,8,0,0,1,11.32,11.32Z"></path> -}.into_view(), -IconWeight::Thin => view! { - <path d="M208,36H180V24a4,4,0,0,0-8,0V36H84V24a4,4,0,0,0-8,0V36H48A12,12,0,0,0,36,48V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V48A12,12,0,0,0,208,36ZM48,44H76V56a4,4,0,0,0,8,0V44h88V56a4,4,0,0,0,8,0V44h28a4,4,0,0,1,4,4V84H44V48A4,4,0,0,1,48,44ZM208,212H48a4,4,0,0,1-4-4V92H212V208A4,4,0,0,1,208,212Zm-53.17-81.17L133.66,152l21.17,21.17a4,4,0,0,1-5.66,5.66L128,157.66l-21.17,21.17a4,4,0,0,1-5.66-5.66L122.34,152l-21.17-21.17a4,4,0,1,1,5.66-5.66L128,146.34l21.17-21.17a4,4,0,1,1,5.66,5.66Z"></path> -}.into_view(), -IconWeight::Bold => view! { - <path d="M160.49,136.49,145,152l15.52,15.51a12,12,0,0,1-17,17L128,169l-15.51,15.52a12,12,0,0,1-17-17L111,152,95.51,136.49a12,12,0,1,1,17-17L128,135l15.51-15.52a12,12,0,1,1,17,17ZM228,48V208a20,20,0,0,1-20,20H48a20,20,0,0,1-20-20V48A20,20,0,0,1,48,28H68V24a12,12,0,0,1,24,0v4h72V24a12,12,0,0,1,24,0v4h20A20,20,0,0,1,228,48ZM52,52V76H204V52H188a12,12,0,0,1-24,0H92a12,12,0,0,1-24,0ZM204,204V100H52V204Z"></path> -}.into_view(), -IconWeight::Light => view! { - <path d="M208,34H182V24a6,6,0,0,0-12,0V34H86V24a6,6,0,0,0-12,0V34H48A14,14,0,0,0,34,48V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V48A14,14,0,0,0,208,34ZM48,46H74V56a6,6,0,0,0,12,0V46h84V56a6,6,0,0,0,12,0V46h26a2,2,0,0,1,2,2V82H46V48A2,2,0,0,1,48,46ZM208,210H48a2,2,0,0,1-2-2V94H210V208A2,2,0,0,1,208,210Zm-51.76-77.76L136.48,152l19.76,19.76a6,6,0,1,1-8.48,8.48L128,160.48l-19.76,19.76a6,6,0,0,1-8.48-8.48L119.52,152,99.76,132.24a6,6,0,1,1,8.48-8.48L128,143.52l19.76-19.76a6,6,0,1,1,8.48,8.48Z"></path> -}.into_view(), -IconWeight::Regular => view! { - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-50.34-74.34L139.31,152l18.35,18.34a8,8,0,0,1-11.32,11.32L128,163.31l-18.34,18.35a8,8,0,0,1-11.32-11.32L116.69,152,98.34,133.66a8,8,0,0,1,11.32-11.32L128,140.69l18.34-18.35a8,8,0,0,1,11.32,11.32Z"></path> -}.into_view() - } - }); + }.into_any(), + IconWeight::Duotone => view! { + <path d="M216,48V88H40V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z" opacity="0.2"></path> + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-50.34-74.34L139.31,152l18.35,18.34a8,8,0,0,1-11.32,11.32L128,163.31l-18.34,18.35a8,8,0,0,1-11.32-11.32L116.69,152,98.34,133.66a8,8,0,0,1,11.32-11.32L128,140.69l18.34-18.35a8,8,0,0,1,11.32,11.32Z"></path> + }.into_any(), + IconWeight::Thin => view! { + <path d="M208,36H180V24a4,4,0,0,0-8,0V36H84V24a4,4,0,0,0-8,0V36H48A12,12,0,0,0,36,48V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V48A12,12,0,0,0,208,36ZM48,44H76V56a4,4,0,0,0,8,0V44h88V56a4,4,0,0,0,8,0V44h28a4,4,0,0,1,4,4V84H44V48A4,4,0,0,1,48,44ZM208,212H48a4,4,0,0,1-4-4V92H212V208A4,4,0,0,1,208,212Zm-53.17-81.17L133.66,152l21.17,21.17a4,4,0,0,1-5.66,5.66L128,157.66l-21.17,21.17a4,4,0,0,1-5.66-5.66L122.34,152l-21.17-21.17a4,4,0,1,1,5.66-5.66L128,146.34l21.17-21.17a4,4,0,1,1,5.66,5.66Z"></path> + }.into_any(), + IconWeight::Bold => view! { + <path d="M160.49,136.49,145,152l15.52,15.51a12,12,0,0,1-17,17L128,169l-15.51,15.52a12,12,0,0,1-17-17L111,152,95.51,136.49a12,12,0,1,1,17-17L128,135l15.51-15.52a12,12,0,1,1,17,17ZM228,48V208a20,20,0,0,1-20,20H48a20,20,0,0,1-20-20V48A20,20,0,0,1,48,28H68V24a12,12,0,0,1,24,0v4h72V24a12,12,0,0,1,24,0v4h20A20,20,0,0,1,228,48ZM52,52V76H204V52H188a12,12,0,0,1-24,0H92a12,12,0,0,1-24,0ZM204,204V100H52V204Z"></path> + }.into_any(), + IconWeight::Light => view! { + <path d="M208,34H182V24a6,6,0,0,0-12,0V34H86V24a6,6,0,0,0-12,0V34H48A14,14,0,0,0,34,48V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V48A14,14,0,0,0,208,34ZM48,46H74V56a6,6,0,0,0,12,0V46h84V56a6,6,0,0,0,12,0V46h26a2,2,0,0,1,2,2V82H46V48A2,2,0,0,1,48,46ZM208,210H48a2,2,0,0,1-2-2V94H210V208A2,2,0,0,1,208,210Zm-51.76-77.76L136.48,152l19.76,19.76a6,6,0,1,1-8.48,8.48L128,160.48l-19.76,19.76a6,6,0,0,1-8.48-8.48L119.52,152,99.76,132.24a6,6,0,1,1,8.48-8.48L128,143.52l19.76-19.76a6,6,0,1,1,8.48,8.48Z"></path> + }.into_any(), + IconWeight::Regular => view! { + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-50.34-74.34L139.31,152l18.35,18.34a8,8,0,0,1-11.32,11.32L128,163.31l-18.34,18.35a8,8,0,0,1-11.32-11.32L116.69,152,98.34,133.66a8,8,0,0,1,11.32-11.32L128,140.69l18.34-18.35a8,8,0,0,1,11.32,11.32Z"></path> + }.into_any() + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -46,8 +39,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/caret_double_right.rs b/aep-schedule-website/src/frontend/components/icons/caret_double_right.rs index 9acd383..83b007a 100644 --- a/aep-schedule-website/src/frontend/components/icons/caret_double_right.rs +++ b/aep-schedule-website/src/frontend/components/icons/caret_double_right.rs @@ -1,44 +1,37 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn CaretDoubleRight( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into, default = IconWeight::Regular)] weight: IconWeight, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = + match weight { IconWeight::Fill => view! { <path d="M221.66,133.66l-80,80A8,8,0,0,1,128,208V147.31L61.66,213.66A8,8,0,0,1,48,208V48a8,8,0,0,1,13.66-5.66L128,108.69V48a8,8,0,0,1,13.66-5.66l80,80A8,8,0,0,1,221.66,133.66Z"></path> - }.into_view(), -IconWeight::Duotone => view! { - <path d="M136,128,56,208V48Z" opacity="0.2"></path> - <path d="M141.66,122.34l-80-80A8,8,0,0,0,48,48V208a8,8,0,0,0,13.66,5.66l80-80A8,8,0,0,0,141.66,122.34ZM64,188.69V67.31L124.69,128Zm157.66-55-80,80a8,8,0,0,1-11.32-11.32L204.69,128,130.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,221.66,133.66Z"></path> -}.into_view(), -IconWeight::Thin => view! { - <path d="M138.83,130.83l-80,80a4,4,0,0,1-5.66-5.66L130.34,128,53.17,50.83a4,4,0,0,1,5.66-5.66l80,80A4,4,0,0,1,138.83,130.83Zm80-5.66-80-80a4,4,0,0,0-5.66,5.66L210.34,128l-77.17,77.17a4,4,0,0,0,5.66,5.66l80-80A4,4,0,0,0,218.83,125.17Z"></path> -}.into_view(), -IconWeight::Bold => view! { - <path d="M144.49,136.49l-80,80a12,12,0,0,1-17-17L119,128,47.51,56.49a12,12,0,0,1,17-17l80,80A12,12,0,0,1,144.49,136.49Zm80-17-80-80a12,12,0,1,0-17,17L199,128l-71.52,71.51a12,12,0,0,0,17,17l80-80A12,12,0,0,0,224.49,119.51Z"></path> -}.into_view(), -IconWeight::Light => view! { - <path d="M140.24,132.24l-80,80a6,6,0,0,1-8.48-8.48L127.51,128,51.76,52.24a6,6,0,0,1,8.48-8.48l80,80A6,6,0,0,1,140.24,132.24Zm80-8.48-80-80a6,6,0,0,0-8.48,8.48L207.51,128l-75.75,75.76a6,6,0,1,0,8.48,8.48l80-80A6,6,0,0,0,220.24,123.76Z"></path> -}.into_view(), -IconWeight::Regular => view! { - <path d="M141.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L124.69,128,50.34,53.66A8,8,0,0,1,61.66,42.34l80,80A8,8,0,0,1,141.66,133.66Zm80-11.32-80-80a8,8,0,0,0-11.32,11.32L204.69,128l-74.35,74.34a8,8,0,0,0,11.32,11.32l80-80A8,8,0,0,0,221.66,122.34Z"></path> -}.into_view() - } - }); + }.into_any(), + IconWeight::Duotone => view! { + <path d="M136,128,56,208V48Z" opacity="0.2"></path> + <path d="M141.66,122.34l-80-80A8,8,0,0,0,48,48V208a8,8,0,0,0,13.66,5.66l80-80A8,8,0,0,0,141.66,122.34ZM64,188.69V67.31L124.69,128Zm157.66-55-80,80a8,8,0,0,1-11.32-11.32L204.69,128,130.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,221.66,133.66Z"></path> + }.into_any(), + IconWeight::Thin => view! { + <path d="M138.83,130.83l-80,80a4,4,0,0,1-5.66-5.66L130.34,128,53.17,50.83a4,4,0,0,1,5.66-5.66l80,80A4,4,0,0,1,138.83,130.83Zm80-5.66-80-80a4,4,0,0,0-5.66,5.66L210.34,128l-77.17,77.17a4,4,0,0,0,5.66,5.66l80-80A4,4,0,0,0,218.83,125.17Z"></path> + }.into_any(), + IconWeight::Bold => view! { + <path d="M144.49,136.49l-80,80a12,12,0,0,1-17-17L119,128,47.51,56.49a12,12,0,0,1,17-17l80,80A12,12,0,0,1,144.49,136.49Zm80-17-80-80a12,12,0,1,0-17,17L199,128l-71.52,71.51a12,12,0,0,0,17,17l80-80A12,12,0,0,0,224.49,119.51Z"></path> + }.into_any(), + IconWeight::Light => view! { + <path d="M140.24,132.24l-80,80a6,6,0,0,1-8.48-8.48L127.51,128,51.76,52.24a6,6,0,0,1,8.48-8.48l80,80A6,6,0,0,1,140.24,132.24Zm80-8.48-80-80a6,6,0,0,0-8.48,8.48L207.51,128l-75.75,75.76a6,6,0,1,0,8.48,8.48l80-80A6,6,0,0,0,220.24,123.76Z"></path> + }.into_any(), + IconWeight::Regular => view! { + <path d="M141.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L124.69,128,50.34,53.66A8,8,0,0,1,61.66,42.34l80,80A8,8,0,0,1,141.66,133.66Zm80-11.32-80-80a8,8,0,0,0-11.32,11.32L204.69,128l-74.35,74.34a8,8,0,0,0,11.32,11.32l80-80A8,8,0,0,0,221.66,122.34Z"></path> + }.into_any() + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -46,8 +39,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/download.rs b/aep-schedule-website/src/frontend/components/icons/download.rs index 2621f72..9bceace 100644 --- a/aep-schedule-website/src/frontend/components/icons/download.rs +++ b/aep-schedule-website/src/frontend/components/icons/download.rs @@ -1,47 +1,40 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn Download( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: IconWeight, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = + match weight { IconWeight::Fill => view! { <path d="M74.34,85.66A8,8,0,0,1,85.66,74.34L120,108.69V24a8,8,0,0,1,16,0v84.69l34.34-34.35a8,8,0,0,1,11.32,11.32l-48,48a8,8,0,0,1-11.32,0ZM240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H84.4a4,4,0,0,1,2.83,1.17L111,145A24,24,0,0,0,145,145l23.8-23.8A4,4,0,0,1,171.6,120H224A16,16,0,0,1,240,136Zm-40,32a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path> - }.into_view(), -IconWeight::Duotone => view! { - <path - d="M232,136v64a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V136a8,8,0,0,1,8-8H224A8,8,0,0,1,232,136Z" - opacity="0.2" - ></path> - <path d="M240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H72a8,8,0,0,1,0,16H32v64H224V136H184a8,8,0,0,1,0-16h40A16,16,0,0,1,240,136Zm-117.66-2.34a8,8,0,0,0,11.32,0l48-48a8,8,0,0,0-11.32-11.32L136,108.69V24a8,8,0,0,0-16,0v84.69L85.66,74.34A8,8,0,0,0,74.34,85.66ZM200,168a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path> -}.into_view(), -IconWeight::Thin => view! { - <path d="M236,136v64a12,12,0,0,1-12,12H32a12,12,0,0,1-12-12V136a12,12,0,0,1,12-12H72a4,4,0,0,1,0,8H32a4,4,0,0,0-4,4v64a4,4,0,0,0,4,4H224a4,4,0,0,0,4-4V136a4,4,0,0,0-4-4H184a4,4,0,0,1,0-8h40A12,12,0,0,1,236,136Zm-110.83-5.17a4,4,0,0,0,5.66,0l48-48a4,4,0,1,0-5.66-5.66L132,118.34V24a4,4,0,0,0-8,0v94.34L82.83,77.17a4,4,0,0,0-5.66,5.66ZM196,168a8,8,0,1,0-8,8A8,8,0,0,0,196,168Z"></path> -}.into_view(), -IconWeight::Bold => view! { - <path d="M71.51,88.49a12,12,0,0,1,17-17L116,99V24a12,12,0,0,1,24,0V99l27.51-27.52a12,12,0,0,1,17,17l-48,48a12,12,0,0,1-17,0ZM224,116H188a12,12,0,0,0,0,24h32v56H36V140H68a12,12,0,0,0,0-24H32a20,20,0,0,0-20,20v64a20,20,0,0,0,20,20H224a20,20,0,0,0,20-20V136A20,20,0,0,0,224,116Zm-20,52a16,16,0,1,0-16,16A16,16,0,0,0,204,168Z"></path> -}.into_view(), -IconWeight::Light => view! { - <path d="M238,136v64a14,14,0,0,1-14,14H32a14,14,0,0,1-14-14V136a14,14,0,0,1,14-14H72a6,6,0,0,1,0,12H32a2,2,0,0,0-2,2v64a2,2,0,0,0,2,2H224a2,2,0,0,0,2-2V136a2,2,0,0,0-2-2H184a6,6,0,0,1,0-12h40A14,14,0,0,1,238,136Zm-114.24-3.76a6,6,0,0,0,8.48,0l48-48a6,6,0,0,0-8.48-8.48L134,113.51V24a6,6,0,0,0-12,0v89.51L84.24,75.76a6,6,0,0,0-8.48,8.48ZM198,168a10,10,0,1,0-10,10A10,10,0,0,0,198,168Z"></path> -}.into_view(), -IconWeight::Regular => view! { - <path d="M240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H72a8,8,0,0,1,0,16H32v64H224V136H184a8,8,0,0,1,0-16h40A16,16,0,0,1,240,136Zm-117.66-2.34a8,8,0,0,0,11.32,0l48-48a8,8,0,0,0-11.32-11.32L136,108.69V24a8,8,0,0,0-16,0v84.69L85.66,74.34A8,8,0,0,0,74.34,85.66ZM200,168a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path> -}.into_view() - } - }); + }.into_any(), + IconWeight::Duotone => view! { + <path + d="M232,136v64a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V136a8,8,0,0,1,8-8H224A8,8,0,0,1,232,136Z" + opacity="0.2" + ></path> + <path d="M240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H72a8,8,0,0,1,0,16H32v64H224V136H184a8,8,0,0,1,0-16h40A16,16,0,0,1,240,136Zm-117.66-2.34a8,8,0,0,0,11.32,0l48-48a8,8,0,0,0-11.32-11.32L136,108.69V24a8,8,0,0,0-16,0v84.69L85.66,74.34A8,8,0,0,0,74.34,85.66ZM200,168a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path> + }.into_any(), + IconWeight::Thin => view! { + <path d="M236,136v64a12,12,0,0,1-12,12H32a12,12,0,0,1-12-12V136a12,12,0,0,1,12-12H72a4,4,0,0,1,0,8H32a4,4,0,0,0-4,4v64a4,4,0,0,0,4,4H224a4,4,0,0,0,4-4V136a4,4,0,0,0-4-4H184a4,4,0,0,1,0-8h40A12,12,0,0,1,236,136Zm-110.83-5.17a4,4,0,0,0,5.66,0l48-48a4,4,0,1,0-5.66-5.66L132,118.34V24a4,4,0,0,0-8,0v94.34L82.83,77.17a4,4,0,0,0-5.66,5.66ZM196,168a8,8,0,1,0-8,8A8,8,0,0,0,196,168Z"></path> + }.into_any(), + IconWeight::Bold => view! { + <path d="M71.51,88.49a12,12,0,0,1,17-17L116,99V24a12,12,0,0,1,24,0V99l27.51-27.52a12,12,0,0,1,17,17l-48,48a12,12,0,0,1-17,0ZM224,116H188a12,12,0,0,0,0,24h32v56H36V140H68a12,12,0,0,0,0-24H32a20,20,0,0,0-20,20v64a20,20,0,0,0,20,20H224a20,20,0,0,0,20-20V136A20,20,0,0,0,224,116Zm-20,52a16,16,0,1,0-16,16A16,16,0,0,0,204,168Z"></path> + }.into_any(), + IconWeight::Light => view! { + <path d="M238,136v64a14,14,0,0,1-14,14H32a14,14,0,0,1-14-14V136a14,14,0,0,1,14-14H72a6,6,0,0,1,0,12H32a2,2,0,0,0-2,2v64a2,2,0,0,0,2,2H224a2,2,0,0,0,2-2V136a2,2,0,0,0-2-2H184a6,6,0,0,1,0-12h40A14,14,0,0,1,238,136Zm-114.24-3.76a6,6,0,0,0,8.48,0l48-48a6,6,0,0,0-8.48-8.48L134,113.51V24a6,6,0,0,0-12,0v89.51L84.24,75.76a6,6,0,0,0-8.48,8.48ZM198,168a10,10,0,1,0-10,10A10,10,0,0,0,198,168Z"></path> + }.into_any(), + IconWeight::Regular => view! { + <path d="M240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H72a8,8,0,0,1,0,16H32v64H224V136H184a8,8,0,0,1,0-16h40A16,16,0,0,1,240,136Zm-117.66-2.34a8,8,0,0,0,11.32,0l48-48a8,8,0,0,0-11.32-11.32L136,108.69V24a8,8,0,0,0-16,0v84.69L85.66,74.34A8,8,0,0,0,74.34,85.66ZM200,168a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path> + }.into_any() + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -49,8 +42,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/gitlab_logo.rs b/aep-schedule-website/src/frontend/components/icons/gitlab_logo.rs index e58337c..1852a3a 100644 --- a/aep-schedule-website/src/frontend/components/icons/gitlab_logo.rs +++ b/aep-schedule-website/src/frontend/components/icons/gitlab_logo.rs @@ -1,47 +1,41 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn GitlabLogo( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: Signal<IconWeight>, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { + let body = move || { match weight.get() { IconWeight::Fill => view! { <path d="M230.15,117.1,210.25,41a11.94,11.94,0,0,0-22.79-1.11L169.78,88H86.22L68.54,39.87A11.94,11.94,0,0,0,45.75,41L25.85,117.1a57.19,57.19,0,0,0,22,61l73.27,51.76a11.91,11.91,0,0,0,13.74,0l73.27-51.76A57.19,57.19,0,0,0,230.15,117.1Zm-189.47,7L114.13,176,93.41,190.65,57.09,165A41.06,41.06,0,0,1,40.68,124.11Zm87.32,91-20.73-14.65L128,185.8l20.73,14.64ZM198.91,165l-36.32,25.66L141.87,176l73.45-51.9A41.06,41.06,0,0,1,198.91,165Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M220.23,110.84,128,176,35.77,110.84,53.5,43A3.93,3.93,0,0,1,61,42.62L80.65,96h94.7L195,42.62a3.93,3.93,0,0,1,7.53.38Z" opacity="0.2" ></path> <path d="M230.15,117.1,210.25,41a11.94,11.94,0,0,0-22.79-1.11L169.78,88H86.22L68.54,39.87A11.94,11.94,0,0,0,45.75,41L25.85,117.1a57.19,57.19,0,0,0,22,61l73.27,51.76a11.91,11.91,0,0,0,13.74,0l73.27-51.76A57.19,57.19,0,0,0,230.15,117.1ZM58,57.5,73.13,98.76A8,8,0,0,0,80.64,104h94.72a8,8,0,0,0,7.51-5.24L198,57.5l13.07,50L128,166.21,44.9,107.5ZM40.68,124.11,114.13,176,93.41,190.65,57.09,165A41.06,41.06,0,0,1,40.68,124.11Zm87.32,91-20.73-14.65L128,185.8l20.73,14.64ZM198.91,165l-36.32,25.66L141.87,176l73.45-51.9A41.06,41.06,0,0,1,198.91,165Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M226.27,118.11,206.38,42a7.94,7.94,0,0,0-15.16-.75L172.57,92H83.43L64.78,41.24A7.94,7.94,0,0,0,49.62,42L29.73,118.11a53.16,53.16,0,0,0,20.44,56.68l73.27,51.76a7.9,7.9,0,0,0,9.12,0l73.27-51.76A53.16,53.16,0,0,0,226.27,118.11Zm-169-74L76.89,97.38A4,4,0,0,0,80.64,100h94.72a4,4,0,0,0,3.75-2.62l19.57-53.22,17,65L128,171.11,40.33,109.17Zm-19.84,76,.7-2.7L121.07,176,93.41,195.54,54.78,168.25A45.11,45.11,0,0,1,37.47,120.14ZM128,220l-27.66-19.54L128,180.9l27.66,19.54Zm73.22-51.73-38.63,27.29L134.93,176l82.9-58.56.7,2.7A45.11,45.11,0,0,1,201.22,168.25Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M234,116.09,214.13,40a15.94,15.94,0,0,0-30.42-1.48L167,84H89L72.29,38.49A15.94,15.94,0,0,0,41.87,40L22,116.09a61.19,61.19,0,0,0,23.57,65.23l73.27,51.77a15.93,15.93,0,0,0,18.36,0l73.27-51.77A61.19,61.19,0,0,0,234,116.09ZM58.61,70.86l10.76,29.28A12,12,0,0,0,80.64,108h94.72a12,12,0,0,0,11.27-7.86l10.76-29.28,9.14,35L128,161.31,49.47,105.83ZM44,131.37,107.2,176l-13.79,9.74-34-24A36.86,36.86,0,0,1,44,131.37Zm84,78.82-13.79-9.75L128,190.7l13.79,9.74Zm68.6-48.47-34,24L148.8,176,212,131.37A36.86,36.86,0,0,1,196.6,161.72Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M228.21,117.61,208.32,41.49a9.94,9.94,0,0,0-19-.93L171.17,90H84.83L66.66,40.56a9.94,9.94,0,0,0-19,.93L27.79,117.61A55.18,55.18,0,0,0,49,176.42l73.27,51.77a9.94,9.94,0,0,0,11.44,0L207,176.42A55.18,55.18,0,0,0,228.21,117.61ZM57.65,50.82,75,98.07A6,6,0,0,0,80.64,102h94.72A6,6,0,0,0,181,98.07l17.36-47.25,15,57.52L128,168.66,42.62,108.34ZM39.38,120.74,117.6,176,93.41,193.1,55.94,166.62A43.1,43.1,0,0,1,39.38,120.74ZM128,217.53l-24.19-17.09L128,183.35l24.19,17.09Zm72.06-50.91L162.59,193.1,138.4,176l78.22-55.26A43.1,43.1,0,0,1,200.06,166.62Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M230.15,117.1,210.25,41a11.94,11.94,0,0,0-22.79-1.11L169.78,88H86.22L68.54,39.87A11.94,11.94,0,0,0,45.75,41L25.85,117.1a57.19,57.19,0,0,0,22,61l73.27,51.76a11.91,11.91,0,0,0,13.74,0l73.27-51.76A57.19,57.19,0,0,0,230.15,117.1ZM58,57.5,73.13,98.76A8,8,0,0,0,80.64,104h94.72a8,8,0,0,0,7.51-5.24L198,57.5l13.07,50L128,166.21,44.9,107.5ZM40.68,124.11,114.13,176,93.41,190.65,57.09,165A41.06,41.06,0,0,1,40.68,124.11Zm87.32,91-20.73-14.65L128,185.8l20.73,14.64ZM198.91,165l-36.32,25.66L141.87,176l73.45-51.9A41.06,41.06,0,0,1,198.91,165Z"></path> -}.into_view() +}.into_any() } - }); + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -49,8 +43,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/house.rs b/aep-schedule-website/src/frontend/components/icons/house.rs index 05a35bc..10a2b42 100644 --- a/aep-schedule-website/src/frontend/components/icons/house.rs +++ b/aep-schedule-website/src/frontend/components/icons/house.rs @@ -1,47 +1,41 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn House( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: Signal<IconWeight>, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { + let body = move || { match weight.get() { IconWeight::Fill => view! { <path d="M224,120v96a8,8,0,0,1-8,8H160a8,8,0,0,1-8-8V164a4,4,0,0,0-4-4H108a4,4,0,0,0-4,4v52a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V120a16,16,0,0,1,4.69-11.31l80-80a16,16,0,0,1,22.62,0l80,80A16,16,0,0,1,224,120Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M216,120v96H152V152H104v64H40V120a8,8,0,0,1,2.34-5.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,216,120Z" opacity="0.2" ></path> <path d="M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M216.49,111.51l-80-80a12,12,0,0,0-17,0l-80,80A12,12,0,0,0,36,120v96a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V156h40v60a4,4,0,0,0,4,4h64a4,4,0,0,0,4-4V120A12,12,0,0,0,216.49,111.51ZM212,212H156V152a4,4,0,0,0-4-4H104a4,4,0,0,0-4,4v60H44V120a4,4,0,0,1,1.17-2.83l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,212,120Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M222.14,105.85l-80-80a20,20,0,0,0-28.28,0l-80,80A19.86,19.86,0,0,0,28,120v96a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V164h24v52a12,12,0,0,0,12,12h64a12,12,0,0,0,12-12V120A19.86,19.86,0,0,0,222.14,105.85ZM204,204H164V152a12,12,0,0,0-12-12H104a12,12,0,0,0-12,12v52H52V121.65l76-76,76,76Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M217.9,110.1l-80-80a14,14,0,0,0-19.8,0l-80,80A13.92,13.92,0,0,0,34,120v96a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V158h36v58a6,6,0,0,0,6,6h64a6,6,0,0,0,6-6V120A13.92,13.92,0,0,0,217.9,110.1ZM210,210H158V152a6,6,0,0,0-6-6H104a6,6,0,0,0-6,6v58H46V120a2,2,0,0,1,.58-1.42l80-80a2,2,0,0,1,2.84,0l80,80A2,2,0,0,1,210,120Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M219.31,108.68l-80-80a16,16,0,0,0-22.62,0l-80,80A15.87,15.87,0,0,0,32,120v96a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V160h32v56a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V120A15.87,15.87,0,0,0,219.31,108.68ZM208,208H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48V120l80-80,80,80Z"></path> -}.into_view() +}.into_any() } - }); + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -49,8 +43,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/plus_circle.rs b/aep-schedule-website/src/frontend/components/icons/plus_circle.rs index 5bd91ad..e4b1f6b 100644 --- a/aep-schedule-website/src/frontend/components/icons/plus_circle.rs +++ b/aep-schedule-website/src/frontend/components/icons/plus_circle.rs @@ -1,53 +1,44 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn PlusCircle( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(default = IconWeight::Regular)] weight: IconWeight, + size: &'static str, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = move || { + match weight { IconWeight::Fill => view! { <path d="M128,24A104,104,0,1,0,232,128,104.13,104.13,0,0,0,128,24Zm40,112H136v32a8,8,0,0,1-16,0V136H88a8,8,0,0,1,0-16h32V88a8,8,0,0,1,16,0v32h32a8,8,0,0,1,0,16Z"></path> - }.into_view(), -IconWeight::Duotone => view! { - <path d="M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z" opacity="0.2"></path> - <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48-88a8,8,0,0,1-8,8H136v32a8,8,0,0,1-16,0V136H88a8,8,0,0,1,0-16h32V88a8,8,0,0,1,16,0v32h32A8,8,0,0,1,176,128Z"></path> -}.into_view(), -IconWeight::Thin => view! { - <path d="M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm44-92a4,4,0,0,1-4,4H132v36a4,4,0,0,1-8,0V132H88a4,4,0,0,1,0-8h36V88a4,4,0,0,1,8,0v36h36A4,4,0,0,1,172,128Z"></path> -}.into_view(), -IconWeight::Bold => view! { - <path d="M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm52-84a12,12,0,0,1-12,12H140v28a12,12,0,0,1-24,0V140H88a12,12,0,0,1,0-24h28V88a12,12,0,0,1,24,0v28h28A12,12,0,0,1,180,128Z"></path> -}.into_view(), -IconWeight::Light => view! { - <path d="M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm46-90a6,6,0,0,1-6,6H134v34a6,6,0,0,1-12,0V134H88a6,6,0,0,1,0-12h34V88a6,6,0,0,1,12,0v34h34A6,6,0,0,1,174,128Z"></path> -}.into_view(), -IconWeight::Regular => view! { - <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48-88a8,8,0,0,1-8,8H136v32a8,8,0,0,1-16,0V136H88a8,8,0,0,1,0-16h32V88a8,8,0,0,1,16,0v32h32A8,8,0,0,1,176,128Z"></path> -}.into_view() + }.into_any(), + IconWeight::Duotone => view! { + <path d="M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z" opacity="0.2"></path> + <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48-88a8,8,0,0,1-8,8H136v32a8,8,0,0,1-16,0V136H88a8,8,0,0,1,0-16h32V88a8,8,0,0,1,16,0v32h32A8,8,0,0,1,176,128Z"></path> + }.into_any(), + IconWeight::Thin => view! { + <path d="M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm44-92a4,4,0,0,1-4,4H132v36a4,4,0,0,1-8,0V132H88a4,4,0,0,1,0-8h36V88a4,4,0,0,1,8,0v36h36A4,4,0,0,1,172,128Z"></path> + }.into_any(), + IconWeight::Bold => view! { + <path d="M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm52-84a12,12,0,0,1-12,12H140v28a12,12,0,0,1-24,0V140H88a12,12,0,0,1,0-24h28V88a12,12,0,0,1,24,0v28h28A12,12,0,0,1,180,128Z"></path> + }.into_any(), + IconWeight::Light => view! { + <path d="M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm46-90a6,6,0,0,1-6,6H134v34a6,6,0,0,1-12,0V134H88a6,6,0,0,1,0-12h34V88a6,6,0,0,1,12,0v34h34A6,6,0,0,1,174,128Z"></path> + }.into_any(), + IconWeight::Regular => view! { + <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48-88a8,8,0,0,1-8,8H136v32a8,8,0,0,1-16,0V136H88a8,8,0,0,1,0-16h32V88a8,8,0,0,1,16,0v32h32A8,8,0,0,1,176,128Z"></path> + }.into_any() } - }); - - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; - let height = size.clone(); + }; view! { <svg xmlns="http://www.w3.org/2000/svg" - width=move || size.get() - height=move || height.get() - fill=color - transform=transform + width=size + height=size + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/sun.rs b/aep-schedule-website/src/frontend/components/icons/sun.rs index 55145ba..cccb877 100644 --- a/aep-schedule-website/src/frontend/components/icons/sun.rs +++ b/aep-schedule-website/src/frontend/components/icons/sun.rs @@ -1,44 +1,38 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn Sun( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: Signal<IconWeight>, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { + let body = move || { match weight.get() { IconWeight::Fill => view! { <path d="M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm8,24a64,64,0,1,0,64,64A64.07,64.07,0,0,0,128,64ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M184,128a56,56,0,1,1-56-56A56,56,0,0,1,184,128Z" opacity="0.2"></path> <path d="M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M124,40V16a4,4,0,0,1,8,0V40a4,4,0,0,1-8,0Zm64,88a60,60,0,1,1-60-60A60.07,60.07,0,0,1,188,128Zm-8,0a52,52,0,1,0-52,52A52.06,52.06,0,0,0,180,128ZM61.17,66.83a4,4,0,0,0,5.66-5.66l-16-16a4,4,0,0,0-5.66,5.66Zm0,122.34-16,16a4,4,0,0,0,5.66,5.66l16-16a4,4,0,0,0-5.66-5.66ZM192,68a4,4,0,0,0,2.83-1.17l16-16a4,4,0,1,0-5.66-5.66l-16,16A4,4,0,0,0,192,68Zm2.83,121.17a4,4,0,0,0-5.66,5.66l16,16a4,4,0,0,0,5.66-5.66ZM40,124H16a4,4,0,0,0,0,8H40a4,4,0,0,0,0-8Zm88,88a4,4,0,0,0-4,4v24a4,4,0,0,0,8,0V216A4,4,0,0,0,128,212Zm112-88H216a4,4,0,0,0,0,8h24a4,4,0,0,0,0-8Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M116,36V20a12,12,0,0,1,24,0V36a12,12,0,0,1-24,0Zm80,92a68,68,0,1,1-68-68A68.07,68.07,0,0,1,196,128Zm-24,0a44,44,0,1,0-44,44A44.05,44.05,0,0,0,172,128ZM51.51,68.49a12,12,0,1,0,17-17l-12-12a12,12,0,0,0-17,17Zm0,119-12,12a12,12,0,0,0,17,17l12-12a12,12,0,1,0-17-17ZM196,72a12,12,0,0,0,8.49-3.51l12-12a12,12,0,0,0-17-17l-12,12A12,12,0,0,0,196,72Zm8.49,115.51a12,12,0,0,0-17,17l12,12a12,12,0,0,0,17-17ZM48,128a12,12,0,0,0-12-12H20a12,12,0,0,0,0,24H36A12,12,0,0,0,48,128Zm80,80a12,12,0,0,0-12,12v16a12,12,0,0,0,24,0V220A12,12,0,0,0,128,208Zm108-92H220a12,12,0,0,0,0,24h16a12,12,0,0,0,0-24Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M122,40V16a6,6,0,0,1,12,0V40a6,6,0,0,1-12,0Zm68,88a62,62,0,1,1-62-62A62.07,62.07,0,0,1,190,128Zm-12,0a50,50,0,1,0-50,50A50.06,50.06,0,0,0,178,128ZM59.76,68.24a6,6,0,1,0,8.48-8.48l-16-16a6,6,0,0,0-8.48,8.48Zm0,119.52-16,16a6,6,0,1,0,8.48,8.48l16-16a6,6,0,1,0-8.48-8.48ZM192,70a6,6,0,0,0,4.24-1.76l16-16a6,6,0,0,0-8.48-8.48l-16,16A6,6,0,0,0,192,70Zm4.24,117.76a6,6,0,0,0-8.48,8.48l16,16a6,6,0,0,0,8.48-8.48ZM46,128a6,6,0,0,0-6-6H16a6,6,0,0,0,0,12H40A6,6,0,0,0,46,128Zm82,82a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V216A6,6,0,0,0,128,210Zm112-88H216a6,6,0,0,0,0,12h24a6,6,0,0,0,0-12Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"></path> -}.into_view() +}.into_any() } - }); + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -46,8 +40,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/sun_horizon.rs b/aep-schedule-website/src/frontend/components/icons/sun_horizon.rs index 5edb7d6..56dee94 100644 --- a/aep-schedule-website/src/frontend/components/icons/sun_horizon.rs +++ b/aep-schedule-website/src/frontend/components/icons/sun_horizon.rs @@ -1,44 +1,38 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn SunHorizon( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into)] weight: Signal<IconWeight>, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { + let body = move || { match weight.get() { IconWeight::Fill => view! { <path d="M248,160a8,8,0,0,1-8,8H16a8,8,0,0,1,0-16H56.45a73.54,73.54,0,0,1-.45-8,72,72,0,0,1,144,0,73.54,73.54,0,0,1-.45,8H240A8,8,0,0,1,248,160Zm-40,32H48a8,8,0,0,0,0,16H208a8,8,0,0,0,0-16ZM80.84,59.58a8,8,0,0,0,14.32-7.16l-8-16a8,8,0,0,0-14.32,7.16ZM20.42,103.16l16,8a8,8,0,1,0,7.16-14.31l-16-8a8,8,0,1,0-7.16,14.31ZM216,112a8,8,0,0,0,3.57-.84l16-8a8,8,0,1,0-7.16-14.31l-16,8A8,8,0,0,0,216,112ZM164.42,63.16a8,8,0,0,0,10.74-3.58l8-16a8,8,0,0,0-14.32-7.16l-8,16A8,8,0,0,0,164.42,63.16Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M192,144a64.33,64.33,0,0,1-2,16H66a64,64,0,1,1,126-16Z" opacity="0.2"></path> <path d="M240,152H199.55a73.54,73.54,0,0,0,.45-8,72,72,0,0,0-144,0,73.54,73.54,0,0,0,.45,8H16a8,8,0,0,0,0,16H240a8,8,0,0,0,0-16ZM72,144a56,56,0,1,1,111.41,8H72.59A56.13,56.13,0,0,1,72,144Zm144,56a8,8,0,0,1-8,8H48a8,8,0,0,1,0-16H208A8,8,0,0,1,216,200ZM72.84,43.58a8,8,0,0,1,14.32-7.16l8,16a8,8,0,0,1-14.32,7.16Zm-56,48.84a8,8,0,0,1,10.74-3.57l16,8a8,8,0,0,1-7.16,14.31l-16-8A8,8,0,0,1,16.84,92.42Zm192,15.16a8,8,0,0,1,3.58-10.73l16-8a8,8,0,1,1,7.16,14.31l-16,8a8,8,0,0,1-10.74-3.58Zm-48-55.16,8-16a8,8,0,0,1,14.32,7.16l-8,16a8,8,0,1,1-14.32-7.16Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M240,156H194.94A68,68,0,1,0,60,144a68.73,68.73,0,0,0,1.06,12H16a4,4,0,0,0,0,8H240a4,4,0,0,0,0-8ZM68,144a60,60,0,1,1,118.79,12H69.21A60.16,60.16,0,0,1,68,144Zm144,56a4,4,0,0,1-4,4H48a4,4,0,0,1,0-8H208A4,4,0,0,1,212,200ZM76.42,41.79a4,4,0,0,1,7.16-3.58l8,16a4,4,0,0,1-7.16,3.58Zm-56,52.42a4,4,0,0,1,5.37-1.79l16,8a4,4,0,0,1-3.58,7.16l-16-8A4,4,0,0,1,20.42,94.21Zm192,11.58a4,4,0,0,1,1.79-5.37l16-8a4,4,0,1,1,3.58,7.16l-16,8a4,4,0,0,1-5.37-1.79Zm-48-51.58,8-16a4,4,0,1,1,7.16,3.58l-8,16a4,4,0,0,1-7.16-3.58Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M240,148H203.89c.07-1.33.11-2.66.11-4a76,76,0,0,0-152,0c0,1.34,0,2.67.11,4H16a12,12,0,0,0,0,24H240a12,12,0,0,0,0-24ZM76,144a52,52,0,0,1,104,0c0,1.34-.07,2.67-.17,4H76.17C76.07,146.67,76,145.34,76,144Zm144,56a12,12,0,0,1-12,12H48a12,12,0,0,1,0-24H208A12,12,0,0,1,220,200ZM12.62,92.21a12,12,0,0,1,15.17-7.59l12,4a12,12,0,1,1-7.58,22.77l-12-4A12,12,0,0,1,12.62,92.21Zm56-48.41a12,12,0,1,1,22.76-7.59l4,12A12,12,0,1,1,72.62,55.8Zm140,60a12,12,0,0,1,7.59-15.18l12-4a12,12,0,0,1,7.58,22.77l-12,4a12,12,0,0,1-15.17-7.59Zm-48-55.59,4-12a12,12,0,1,1,22.76,7.59l-4,12a12,12,0,1,1-22.76-7.59Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M240,154H197.28a70.91,70.91,0,0,0,.72-10,70,70,0,0,0-140,0,70.91,70.91,0,0,0,.72,10H16a6,6,0,0,0,0,12H240a6,6,0,0,0,0-12ZM70,144a58,58,0,1,1,115.13,10H70.87A58.63,58.63,0,0,1,70,144Zm144,56a6,6,0,0,1-6,6H48a6,6,0,0,1,0-12H208A6,6,0,0,1,214,200ZM74.63,42.69a6,6,0,0,1,10.74-5.37l8,16a6,6,0,0,1-10.74,5.36Zm-56,50.63a6,6,0,0,1,8.05-2.69l16,8a6,6,0,0,1-5.36,10.74l-16-8A6,6,0,0,1,18.63,93.32Zm192,13.36a6,6,0,0,1,2.69-8.05l16-8a6,6,0,1,1,5.36,10.74l-16,8a6,6,0,0,1-8.05-2.69Zm-48-53.36,8-16a6,6,0,0,1,10.74,5.37l-8,16a6,6,0,1,1-10.74-5.36Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M240,152H199.55a73.54,73.54,0,0,0,.45-8,72,72,0,0,0-144,0,73.54,73.54,0,0,0,.45,8H16a8,8,0,0,0,0,16H240a8,8,0,0,0,0-16ZM72,144a56,56,0,1,1,111.41,8H72.59A56.13,56.13,0,0,1,72,144Zm144,56a8,8,0,0,1-8,8H48a8,8,0,0,1,0-16H208A8,8,0,0,1,216,200ZM72.84,43.58a8,8,0,0,1,14.32-7.16l8,16a8,8,0,0,1-14.32,7.16Zm-56,48.84a8,8,0,0,1,10.74-3.57l16,8a8,8,0,0,1-7.16,14.31l-16-8A8,8,0,0,1,16.84,92.42Zm192,15.16a8,8,0,0,1,3.58-10.73l16-8a8,8,0,1,1,7.16,14.31l-16,8a8,8,0,0,1-10.74-3.58Zm-48-55.16,8-16a8,8,0,0,1,14.32,7.16l-8,16a8,8,0,1,1-14.32-7.16Z"></path> -}.into_view() +}.into_any() } - }); + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -46,8 +40,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/warning_circle.rs b/aep-schedule-website/src/frontend/components/icons/warning_circle.rs index 2e7db7b..75dc967 100644 --- a/aep-schedule-website/src/frontend/components/icons/warning_circle.rs +++ b/aep-schedule-website/src/frontend/components/icons/warning_circle.rs @@ -1,44 +1,37 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn WarningCircle( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into, default = IconWeight::Regular)] weight: IconWeight, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = + match weight { IconWeight::Fill => view! { <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-8,56a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm8,104a12,12,0,1,1,12-12A12,12,0,0,1,128,184Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z" opacity="0.2"></path> <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm-4-84V80a4,4,0,0,1,8,0v56a4,4,0,0,1-8,0Zm12,36a8,8,0,1,1-8-8A8,8,0,0,1,136,172Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm-12-80V80a12,12,0,0,1,24,0v52a12,12,0,0,1-24,0Zm28,40a16,16,0,1,1-16-16A16,16,0,0,1,144,172Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm-6-82V80a6,6,0,0,1,12,0v56a6,6,0,0,1-12,0Zm16,36a10,10,0,1,1-10-10A10,10,0,0,1,138,172Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z"></path> -}.into_view() - } - }); +}.into_any() + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -46,8 +39,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/icons/x.rs b/aep-schedule-website/src/frontend/components/icons/x.rs index 0d3d03e..cb32c13 100644 --- a/aep-schedule-website/src/frontend/components/icons/x.rs +++ b/aep-schedule-website/src/frontend/components/icons/x.rs @@ -1,47 +1,40 @@ -//! GENERATED FILE - use super::IconWeight; -use leptos::*; +use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn X( - #[prop(into, default = MaybeSignal::Static(IconWeight::Regular))] weight: MaybeSignal< - IconWeight, - >, - #[prop(into, default = TextProp::from("1em"))] size: TextProp, + #[prop(into, default = IconWeight::Regular)] weight: IconWeight, + #[prop(into)] size: TextProp, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, default = MaybeSignal::Static(false))] mirrored: MaybeSignal<bool>, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = Signal::derive(move || { - match weight.get() { + let body = + match weight { IconWeight::Fill => view! { <path d="M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM181.66,170.34a8,8,0,0,1-11.32,11.32L128,139.31,85.66,181.66a8,8,0,0,1-11.32-11.32L116.69,128,74.34,85.66A8,8,0,0,1,85.66,74.34L128,116.69l42.34-42.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path> - }.into_view(), + }.into_any(), IconWeight::Duotone => view! { <path d="M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z" opacity="0.2" ></path> <path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path> -}.into_view(), +}.into_any(), IconWeight::Thin => view! { <path d="M202.83,197.17a4,4,0,0,1-5.66,5.66L128,133.66,58.83,202.83a4,4,0,0,1-5.66-5.66L122.34,128,53.17,58.83a4,4,0,0,1,5.66-5.66L128,122.34l69.17-69.17a4,4,0,1,1,5.66,5.66L133.66,128Z"></path> -}.into_view(), +}.into_any(), IconWeight::Bold => view! { <path d="M208.49,191.51a12,12,0,0,1-17,17L128,145,64.49,208.49a12,12,0,0,1-17-17L111,128,47.51,64.49a12,12,0,0,1,17-17L128,111l63.51-63.52a12,12,0,0,1,17,17L145,128Z"></path> -}.into_view(), +}.into_any(), IconWeight::Light => view! { <path d="M204.24,195.76a6,6,0,1,1-8.48,8.48L128,136.49,60.24,204.24a6,6,0,0,1-8.48-8.48L119.51,128,51.76,60.24a6,6,0,0,1,8.48-8.48L128,119.51l67.76-67.75a6,6,0,0,1,8.48,8.48L136.49,128Z"></path> -}.into_view(), +}.into_any(), IconWeight::Regular => view! { <path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path> -}.into_view() - } - }); +}.into_any() + }; - let transform = move || if mirrored.get() { "scale(-1, 1)" } else { "" }; let height = size.clone(); view! { @@ -49,8 +42,7 @@ IconWeight::Regular => view! { xmlns="http://www.w3.org/2000/svg" width=move || size.get() height=move || height.get() - fill=color - transform=transform + fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) diff --git a/aep-schedule-website/src/frontend/components/notifications.rs b/aep-schedule-website/src/frontend/components/notifications.rs index a701a72..b8adfe6 100644 --- a/aep-schedule-website/src/frontend/components/notifications.rs +++ b/aep-schedule-website/src/frontend/components/notifications.rs @@ -1,5 +1,5 @@ use aep_schedule_generator::data::group_sigle::SigleGroup; -use leptos::*; +use leptos::{html, prelude::*, task::spawn_local}; use crate::{ backend::{ @@ -14,11 +14,11 @@ pub fn Notifications( modal: ReadSignal<Option<SigleGroup>>, set_modal: WriteSignal<Option<SigleGroup>>, ) -> impl IntoView { - let input_element: NodeRef<html::Input> = create_node_ref(); + let input_element: NodeRef<html::Input> = NodeRef::new(); let on_submit = move |ev: leptos::ev::SubmitEvent| { ev.prevent_default(); - let email = input_element().unwrap().value(); + let email = input_element.get().unwrap().value(); if email.is_empty() { return; } diff --git a/aep-schedule-website/src/frontend/components/options/courses_selector.rs b/aep-schedule-website/src/frontend/components/options/courses_selector.rs index 162309c..c08030e 100644 --- a/aep-schedule-website/src/frontend/components/options/courses_selector.rs +++ b/aep-schedule-website/src/frontend/components/options/courses_selector.rs @@ -1,34 +1,34 @@ use crate::backend::routes::get_courses; use crate::frontend::components::common::tab::Tab; -use crate::frontend::components::icons::bell_ringing::BellRinging; +// use crate::frontend::components::icons::bell_ringing::BellRinging; use crate::frontend::components::icons::calendar_x::CalendarX; use crate::frontend::components::icons::x::X; use crate::frontend::components::icons::IconWeight; use crate::frontend::components::options::personal::PersonalTimeSelector; use crate::frontend::components::options::search::SearchCourse; -use crate::frontend::pages::generator::SetModal; +// use crate::frontend::pages::generator::SetModal; use crate::frontend::state::reactive_course::ReactiveCourse; use crate::frontend::state::reactive_course::ReactiveCourseType; use crate::frontend::state::OptionState; use aep_schedule_generator::data::group::Group; use aep_schedule_generator::data::group_sigle::GroupType; -use aep_schedule_generator::data::group_sigle::SigleGroup; +// use aep_schedule_generator::data::group_sigle::SigleGroup; use aep_schedule_generator::data::groups::Groups; use compact_str::CompactString; -use leptos::*; +use leptos::prelude::*; #[component] fn GroupsChips<F>( open: RwSignal<bool>, group: Group, - course_sigle: CompactString, - group_type: GroupType, + _course_sigle: CompactString, + _group_type: GroupType, submit: F, ) -> impl IntoView where F: Fn() + Copy + 'static, { - let set_modal = SetModal::from_context(); + // let set_modal = SetModal::from_context(); view! { <div on:pointerdown=move |_| { @@ -82,7 +82,7 @@ where {groups.into_iter().enumerate().map(|(i, group)| { let open = open[i]; view! { - <GroupsChips open group course_sigle=course_sigle.clone() group_type submit/> + <GroupsChips open group _course_sigle=course_sigle.clone() _group_type=group_type submit/> } }).collect_view() } @@ -92,7 +92,7 @@ where #[component] fn CourseTab<F>(course: ReactiveCourse, active_tab: ReadSignal<String>, submit: F) -> impl IntoView where - F: Fn() + Copy + 'static, + F: Fn() + Copy + 'static + Send, { let course_sigle = course.sigle.clone(); view! { @@ -108,7 +108,7 @@ where <h3>"Théorie"</h3> <GroupsSettings groups open=theo_open course_sigle group_type=GroupType::TheoGroup submit/> </div> - }.into_view() + }.into_any() }, ReactiveCourseType::LabOnly { lab_open, lab_groups } => { let groups = lab_groups; @@ -117,7 +117,7 @@ where <h3>"Laboratoire"</h3> <GroupsSettings groups open=lab_open course_sigle=course_sigle.clone() group_type=GroupType::LabGroup submit/> </div> - }.into_view() + }.into_any() }, ReactiveCourseType::Both { theo_open, theo_groups, lab_open, lab_groups } => { let theo_groups = theo_groups; @@ -132,7 +132,7 @@ where <h3>"Laboratoire"</h3> <GroupsSettings groups=lab_groups open=lab_open course_sigle=course_sigle.clone() group_type=GroupType::LabGroup submit/> </div> - }.into_view() + }.into_any() }, ReactiveCourseType::Linked { both_open, theo_groups, lab_groups } => { let groups = theo_groups.merge(lab_groups); @@ -141,7 +141,7 @@ where <h3>"Théorie et laboratoire lié"</h3> <GroupsSettings groups open=both_open course_sigle=course_sigle group_type=GroupType::LabGroup submit/> </div> - }.into_view() + }.into_any() }, } } @@ -153,15 +153,15 @@ where #[component] pub fn CoursesSelector<F>(state: OptionState, submit: F) -> impl IntoView where - F: Fn() + Copy + 'static, + F: Fn() + Copy + 'static + Send, { - let (active_tab, set_active_tab) = create_signal("".to_string()); + let (active_tab, set_active_tab) = signal("".to_string()); let action_courses = state.action_courses; view! { <Await - future=get_courses + future=get_courses() let:courses > <SearchCourse courses=courses.clone() action_courses set_active_tab/> @@ -180,12 +180,14 @@ where let sigle = course.sigle.to_string(); let add_hidden = move || sigle != active_tab.get(); let sigle = course.sigle.to_string(); + let sigle2 = course.sigle.to_string(); + let sigle3 = course.sigle.to_string(); view!{ - <button class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" class=("opacity-75", add_hidden) id=&sigle on:pointerdown={ + <button class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" class=("opacity-75", add_hidden) id=sigle3 on:pointerdown={ let sigle = sigle.clone(); move |_| set_active_tab.set(sigle.clone()) }> - {&sigle} + {sigle2} <button class="close" on:pointerdown={ let sigle = sigle.clone(); move |_| { @@ -199,7 +201,8 @@ where }); submit(); } - }><X weight=IconWeight::Regular size="16px"/></button> + }> + <X weight=IconWeight::Regular size="16px"/></button> </button> } } diff --git a/aep-schedule-website/src/frontend/components/options/form.rs b/aep-schedule-website/src/frontend/components/options/form.rs index 07d06d6..e88fb50 100644 --- a/aep-schedule-website/src/frontend/components/options/form.rs +++ b/aep-schedule-website/src/frontend/components/options/form.rs @@ -6,7 +6,7 @@ use crate::frontend::{ pages::generator::FirstGenerationDone, state::OptionState, }; -use leptos::*; +use leptos::prelude::*; #[component] pub fn OptionsForms() -> impl IntoView { @@ -21,7 +21,8 @@ pub fn OptionsForms() -> impl IntoView { state.generate(); }; - create_local_resource(state.action_courses.pending(), move |_| { + Effect::new(move |_| { + state.action_courses.pending().track(); submit(); async move {} }); diff --git a/aep-schedule-website/src/frontend/components/options/optimizations.rs b/aep-schedule-website/src/frontend/components/options/optimizations.rs index 074d766..f0541af 100644 --- a/aep-schedule-website/src/frontend/components/options/optimizations.rs +++ b/aep-schedule-website/src/frontend/components/options/optimizations.rs @@ -4,7 +4,7 @@ use crate::frontend::{ }, state::OptionState, }; -use leptos::*; +use leptos::prelude::*; use std::cmp; fn weight(input: u8) -> IconWeight { @@ -22,10 +22,10 @@ pub fn SelectOptimizations<F>(state: OptionState, submit: F) -> impl IntoView where F: Fn() + Copy + 'static, { - let weight_house = create_memo(move |_| weight(state.day_off.get())); - let weight_early = create_memo(move |_| weight((-cmp::min(0, state.morning.get())) as u8)); - let weight_morning = create_memo(move |_| weight(cmp::max(0, state.morning.get()) as u8)); - let weight_finish = create_memo(move |_| weight(state.finish_early.get())); + let weight_house = Memo::new(move |_| weight(state.day_off.get())); + let weight_early = Memo::new(move |_| weight((-cmp::min(0, state.morning.get())) as u8)); + let weight_morning = Memo::new(move |_| weight(cmp::max(0, state.morning.get()) as u8)); + let weight_finish = Memo::new(move |_| weight(state.finish_early.get())); view! { <div class="three-col"> diff --git a/aep-schedule-website/src/frontend/components/options/personal.rs b/aep-schedule-website/src/frontend/components/options/personal.rs index bcfebc1..fa342b8 100644 --- a/aep-schedule-website/src/frontend/components/options/personal.rs +++ b/aep-schedule-website/src/frontend/components/options/personal.rs @@ -1,5 +1,5 @@ use crate::frontend::components::common::schedule::Schedule; -use leptos::*; +use leptos::{ev, prelude::*}; use web_sys::wasm_bindgen::JsCast; use web_sys::Element; @@ -8,9 +8,9 @@ pub fn PersonalTimeSelector<F>(week: [RwSignal<u64>; 5], submit: F) -> impl Into where F: Fn() + Copy + 'static, { - let (initial, set_initial) = create_signal(None); - let (destination, set_destination) = create_signal((0, 0)); - let (is_positive, set_positive) = create_signal(true); + let (initial, set_initial) = signal(None); + let (destination, set_destination) = signal((0, 0)); + let (is_positive, set_positive) = signal(true); let selection = move || { let Some((initial_x, initial_y)) = initial.get() else { return String::from("display: none;"); diff --git a/aep-schedule-website/src/frontend/components/options/search.rs b/aep-schedule-website/src/frontend/components/options/search.rs index 12a223f..9980493 100644 --- a/aep-schedule-website/src/frontend/components/options/search.rs +++ b/aep-schedule-website/src/frontend/components/options/search.rs @@ -3,7 +3,7 @@ use crate::frontend::{ state::reactive_course::ReactiveCourse, }; use aep_schedule_generator::data::course::CourseName; -use leptos::*; +use leptos::prelude::*; #[component] pub fn SearchCourse( diff --git a/aep-schedule-website/src/frontend/components/options/todo.rs b/aep-schedule-website/src/frontend/components/options/todo.rs index 755e463..38c51e0 100644 --- a/aep-schedule-website/src/frontend/components/options/todo.rs +++ b/aep-schedule-website/src/frontend/components/options/todo.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use crate::frontend::components::icons::warning_circle::WarningCircle; use crate::frontend::{pages::generator::FirstGenerationDone, state::OptionState}; -use leptos::*; +use leptos::prelude::*; #[component] pub fn Step( diff --git a/aep-schedule-website/src/frontend/components/schedule.rs b/aep-schedule-website/src/frontend/components/schedule.rs index 1aefa47..e7c4cc7 100644 --- a/aep-schedule-website/src/frontend/components/schedule.rs +++ b/aep-schedule-website/src/frontend/components/schedule.rs @@ -1,4 +1,4 @@ -use std::rc::Rc; +use std::sync::Arc; use crate::frontend::components::common::schedule::{Schedule, ScheduleEvent}; use crate::frontend::components::icons::download::Download; @@ -11,10 +11,10 @@ use aep_schedule_generator::{ }, data::time::{period::Period, week_number::WeekNumber}, }; -use leptos::{html::A, *}; +use leptos::prelude::*; #[component] -pub fn Course<'a>(i: usize, course: &'a TakenCourse) -> impl IntoView { +pub fn Course(i: usize, course: TakenCourse) -> impl IntoView { let theo_group = course.theo_group().map(|g| format!("T: {}", g.number)); let lab_group = course.lab_group().map(|g| format!("L: {}", g.number)); let color_box = match i % 8 { @@ -42,10 +42,10 @@ pub fn Course<'a>(i: usize, course: &'a TakenCourse) -> impl IntoView { } #[component] -fn PeriodEvent<'a>( +fn PeriodEvent( i: usize, - period: &'a Period, - course: &'a TakenCourse, + period: Period, + course: Arc<TakenCourse>, period_type: &'static str, ) -> impl IntoView { let mut location = period.hours.to_string() + " - " + period.room.as_str(); @@ -73,7 +73,7 @@ fn PeriodEvent<'a>( } view! { - <ScheduleEvent period=&period class=class> + <ScheduleEvent period=period class=class> <span>{location}</span> <span>{sigle}</span> </ScheduleEvent> @@ -81,22 +81,28 @@ fn PeriodEvent<'a>( } #[component] -fn CoursePeriods<'a>(i: usize, course: &'a TakenCourse) -> impl IntoView { - match &course.taken_course_type { +fn CoursePeriods(i: usize, course: TakenCourse) -> impl IntoView { + let taken_course_type = course.taken_course_type.clone(); + let course = Arc::new(course); + match taken_course_type { TakenCourseType::TheoOnly { theo_group } => theo_group .periods - .iter() + .into_iter() .map(|p| { - view! {<PeriodEvent i period=&p course=course period_type="T"/>} + let course = Arc::clone(&course); + view! {<PeriodEvent i period=p course period_type="T"/>} }) - .collect_view(), + .collect_view() + .into_any(), TakenCourseType::LabOnly { lab_group } => lab_group .periods - .iter() + .into_iter() .map(|p| { - view! {<PeriodEvent i period=&p course=course period_type="L"/>} + let course = Arc::clone(&course); + view! {<PeriodEvent i period=p course period_type="L"/>} }) - .collect_view(), + .collect_view() + .into_any(), TakenCourseType::Both { theo_group, lab_group, @@ -106,40 +112,44 @@ fn CoursePeriods<'a>(i: usize, course: &'a TakenCourse) -> impl IntoView { lab_group, } => view! { { - theo_group.periods.iter().map(|p| { - view! {<PeriodEvent i period=&p course=course period_type="T"/>} + theo_group.periods.into_iter().map(|p| { + let course = Arc::clone(&course); + view! {<PeriodEvent i period=p course period_type="T"/>} }).collect_view() } { - lab_group.periods.iter().map(|p| { - view! {<PeriodEvent i period=&p course=course period_type="L"/>} + lab_group.periods.into_iter().map(|p| { + let course = Arc::clone(&course); + view! {<PeriodEvent i period=p course period_type="L"/>} }).collect_view() } } - .into_view(), + .into_any(), } } #[component] -pub fn ScheduleComponent(schedule: Schedule, calendar: Rc<Calendar>) -> impl IntoView { +pub fn ScheduleComponent(schedule: Schedule, calendar: Arc<Calendar>) -> impl IntoView { + let courses = schedule.taken_courses.clone(); + let courses2 = schedule.taken_courses.clone(); let schedule2 = schedule.clone(); - let (download, set_download) = create_signal("".to_string()); - let link: NodeRef<A> = create_node_ref(); + let (download, set_download) = signal("".to_string()); + let link = NodeRef::new(); view! { <div class="flex flex-col w-full items-center card p-2"> <a class="hidden" download="cours.ics" href=move || download.get() node_ref=link></a> <table class="cours"> - {schedule.taken_courses.iter().enumerate().map(|(i, c)| view!{<Course i course={c} />}).collect_view()} + {courses.into_iter().enumerate().map(|(i, c)| view!{<Course i course={c} />}).collect_view()} </table> <Schedule last_day=schedule.last_day> - {schedule.taken_courses.iter().enumerate().map(|(i, c)| view!{<CoursePeriods i course=c />}).collect_view()} + {courses2.into_iter().enumerate().map(|(i, c)| view!{<CoursePeriods i course=c />}).collect_view()} </Schedule> <button class="button-download flex" on:pointerdown=move |_| { let ics = calendar.generate_ics(&schedule2); let url = url_escape::encode_fragment(&ics); set_download("data:text/plain;charset=utf-8,".to_string() + &url); - link().unwrap().click(); + link.get().unwrap().click(); }> <Download weight=IconWeight::Regular size="3vh"/> <span>"Télécharger le calendrier de cet horaire"</span> diff --git a/aep-schedule-website/src/frontend/components/schedules.rs b/aep-schedule-website/src/frontend/components/schedules.rs index 9108636..17f3d96 100644 --- a/aep-schedule-website/src/frontend/components/schedules.rs +++ b/aep-schedule-website/src/frontend/components/schedules.rs @@ -1,10 +1,10 @@ -use std::rc::Rc; +use std::sync::Arc; use crate::frontend::components::icons::warning_circle::WarningCircle; use crate::frontend::components::options::todo::Todo; use crate::frontend::state::OptionState; use crate::{backend::routes::get_calendar, frontend::components::schedule::ScheduleComponent}; -use leptos::*; +use leptos::prelude::*; #[component] pub fn SchedulesComponent() -> impl IntoView { @@ -12,25 +12,25 @@ pub fn SchedulesComponent() -> impl IntoView { view! { <Await - future=get_calendar + future=get_calendar() children=move |calendar| { let bad_generation = state.schedule.get().is_empty(); let generated = state.step.get() == 6; match generated && !bad_generation { true => { - let calendar = Rc::new(calendar.clone().unwrap()); + let calendar = Arc::new(calendar.clone().unwrap()); view !{ <For each=move || state.schedule.get() key= |course| course.id children= move |schedule| { - let calendar = Rc::clone(&calendar); + let calendar = Arc::clone(&calendar); view !{ <ScheduleComponent schedule calendar/> } } /> - }.into_view() + }.into_any() }, _ => view ! { <Todo/> @@ -47,7 +47,7 @@ pub fn SchedulesComponent() -> impl IntoView { false => None, } } - }.into_view() + }.into_any() } } /> diff --git a/aep-schedule-website/src/frontend/pages/apropos.rs b/aep-schedule-website/src/frontend/pages/apropos.rs index 04e5edc..4921cbc 100644 --- a/aep-schedule-website/src/frontend/pages/apropos.rs +++ b/aep-schedule-website/src/frontend/pages/apropos.rs @@ -1,4 +1,4 @@ -use leptos::*; +use leptos::prelude::*; #[component] pub fn HomePage() -> impl IntoView { diff --git a/aep-schedule-website/src/frontend/pages/classroom.rs b/aep-schedule-website/src/frontend/pages/classroom.rs index a3576be..dbb2186 100644 --- a/aep-schedule-website/src/frontend/pages/classroom.rs +++ b/aep-schedule-website/src/frontend/pages/classroom.rs @@ -7,10 +7,10 @@ use crate::{ }, }; use aep_schedule_generator::data::time::{period::PeriodCourse, week_number::WeekNumber}; -use leptos::*; +use leptos::prelude::*; #[component] -fn PeriodEvent<'a>(i: usize, period_course: &'a PeriodCourse) -> impl IntoView { +fn PeriodEvent(i: usize, period_course: PeriodCourse) -> impl IntoView { let time = period_course.period.hours.to_string(); let sigle = period_course.sigle.to_string(); @@ -26,8 +26,10 @@ fn PeriodEvent<'a>(i: usize, period_course: &'a PeriodCourse) -> impl IntoView { _ => (), } + let period = period_course.period.clone(); + view! { - <ScheduleEvent period=&period_course.period class=class> + <ScheduleEvent period=period class=class> <span>{sigle}</span> <span>{time}</span> </ScheduleEvent> @@ -36,10 +38,10 @@ fn PeriodEvent<'a>(i: usize, period_course: &'a PeriodCourse) -> impl IntoView { #[component] pub fn ClassRoomComponent() -> impl IntoView { - let (periods, set_periods) = create_signal(vec![]); + let (periods, set_periods) = signal(vec![]); let change_classroom = - create_action(|(room, set): &(String, WriteSignal<Vec<PeriodCourse>>)| { + Action::new(|(room, set): &(String, WriteSignal<Vec<PeriodCourse>>)| { let set = *set; let room = room.clone(); async move { @@ -49,7 +51,7 @@ pub fn ClassRoomComponent() -> impl IntoView { } }); - let on_submit = move |sigle: String| change_classroom.dispatch((sigle, set_periods)); + let on_submit = move |sigle: String| {change_classroom.dispatch((sigle, set_periods));}; view! { <section class="flex flex-col w-full justify-between items-center p-4"> <div class="warning-box"> @@ -60,18 +62,18 @@ pub fn ClassRoomComponent() -> impl IntoView { </span> </div> <Await - future=|| get_classrooms() + future=get_classrooms() let:classrooms > {classrooms.as_ref().map(|classrooms| { - let classrooms = classrooms.iter().map(|c| AutoCompleteOption::new(c.to_string(), c.to_string())).collect(); + let classrooms = classrooms.into_iter().map(|c| AutoCompleteOption::new(c.to_string(), c.to_string())).collect(); view!{ <AutoComplete suggestion_list=classrooms placeholder="Local" class="w-96 shadow-2xl border-b-4 border-amber-500 focus:outline-none focus:ring-0" submit=on_submit id="input-classroom"/> } }).ok()} </Await> <Schedule last_day=5 col_height="0.6em"> - {move || periods.get().iter().enumerate().map(|(i, p)| view!{<PeriodEvent i period_course=p/>}).collect_view()} + {move || periods.get().into_iter().enumerate().map(|(i, p)| view!{<PeriodEvent i period_course=p/>}).collect_view()} </Schedule> </section> } diff --git a/aep-schedule-website/src/frontend/pages/generator.rs b/aep-schedule-website/src/frontend/pages/generator.rs index d7fdf57..bdba427 100644 --- a/aep-schedule-website/src/frontend/pages/generator.rs +++ b/aep-schedule-website/src/frontend/pages/generator.rs @@ -3,7 +3,7 @@ use crate::frontend::components::notifications::Notifications; use crate::frontend::components::{options::form::OptionsForms, schedules::SchedulesComponent}; use crate::frontend::state::OptionState; use aep_schedule_generator::data::group_sigle::SigleGroup; -use leptos::*; +use leptos::prelude::*; #[derive(Clone, Copy)] pub struct SetModal(WriteSignal<Option<SigleGroup>>); @@ -19,8 +19,8 @@ pub struct FirstGenerationDone(pub RwSignal<bool>); #[component] pub fn GeneratorPage() -> impl IntoView { - let first_generation_done = create_rw_signal(false); - let (modal, set_modal) = create_signal(None); + let first_generation_done = RwSignal::new(false); + let (modal, set_modal) = signal(None); let state = OptionState::default(); provide_context(state); diff --git a/aep-schedule-website/src/frontend/state/mod.rs b/aep-schedule-website/src/frontend/state/mod.rs index 6904f0a..3657e6b 100644 --- a/aep-schedule-website/src/frontend/state/mod.rs +++ b/aep-schedule-website/src/frontend/state/mod.rs @@ -4,7 +4,7 @@ use aep_schedule_generator::{ algorithm::{generation::SchedulesOptions, schedule::Schedule, scores::EvaluationOption}, data::time::week::Week, }; -use leptos::*; +use leptos::prelude::*; use reactive_course::ReactiveCourse; use crate::backend::routes::get_course; @@ -100,9 +100,9 @@ impl OptionState { impl Default for OptionState { fn default() -> Self { - let stored_courses: StoredValue<Vec<ReactiveCourse>> = store_value(vec![]); + let stored_courses: StoredValue<Vec<ReactiveCourse>> = StoredValue::new(vec![]); - let action_courses = create_action(move |sigle: &String| { + let action_courses = Action::new(move |sigle: &String| { let sigle = sigle.clone(); async move { if let Ok(c) = get_course(sigle).await { @@ -121,17 +121,17 @@ impl Default for OptionState { Self { stored_courses, action_courses, - max_nb_conflicts: create_rw_signal(0), - week: std::array::from_fn(|_i| create_rw_signal(0)), - day_off: create_rw_signal(3), - morning: create_rw_signal(1), - finish_early: create_rw_signal(1), - section_error: create_rw_signal("".to_string()), - personal_error: create_rw_signal("".to_string()), - step: create_rw_signal(0), - schedule: create_rw_signal(vec![]), - hide: create_rw_signal(false), - max_size: store_value(AtomicUsize::from(8)), + max_nb_conflicts: RwSignal::new(0), + week: std::array::from_fn(|_i| RwSignal::new(0)), + day_off: RwSignal::new(3), + morning: RwSignal::new(1), + finish_early: RwSignal::new(1), + section_error: RwSignal::new("".to_string()), + personal_error: RwSignal::new("".to_string()), + step: RwSignal::new(0), + schedule: RwSignal::new(vec![]), + hide: RwSignal::new(false), + max_size: StoredValue::new(AtomicUsize::from(8)), } } } diff --git a/aep-schedule-website/src/frontend/state/reactive_course.rs b/aep-schedule-website/src/frontend/state/reactive_course.rs index 3e6b064..2bda6cd 100644 --- a/aep-schedule-website/src/frontend/state/reactive_course.rs +++ b/aep-schedule-website/src/frontend/state/reactive_course.rs @@ -1,6 +1,6 @@ use aep_schedule_generator::data::{course::Course, course_type::CourseType, groups::Groups}; use compact_str::CompactString; -use leptos::*; +use leptos::prelude::*; #[derive(Clone, Debug)] pub enum ReactiveCourseType { diff --git a/aep-schedule-website/src/lib.rs b/aep-schedule-website/src/lib.rs index d0e2c08..da5d161 100644 --- a/aep-schedule-website/src/lib.rs +++ b/aep-schedule-website/src/lib.rs @@ -3,7 +3,7 @@ pub mod backend; pub mod frontend; cfg_if::cfg_if! { if #[cfg(feature = "hydrate")] { - use leptos::*; + use leptos::prelude::*; use wasm_bindgen::prelude::wasm_bindgen; use crate::frontend::app::App; diff --git a/aep-schedule-website/src/main.rs b/aep-schedule-website/src/main.rs index 7f2f1bf..ae90c0a 100644 --- a/aep-schedule-website/src/main.rs +++ b/aep-schedule-website/src/main.rs @@ -5,7 +5,7 @@ cfg_if::cfg_if!(if #[cfg(feature = "ssr")] { }; use std::future::IntoFuture; use leptos_axum::{generate_route_list, LeptosRoutes}; - use leptos::*; + use leptos::prelude::*; use tower_http::compression::CompressionLayer; use aep_schedule_website::backend::fileserv::file_and_error_handler; use aep_schedule_website::frontend::app::App; -- GitLab From ceb99599086862fcfcf660410eb5d5bb123f96bf Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Sat, 23 Nov 2024 18:15:48 -0500 Subject: [PATCH 09/15] feat: finish server integration, more optimization is needed and fixes --- aep-schedule-website/src/backend/fileserv.rs | 2 +- aep-schedule-website/src/backend/state.rs | 16 ++++++++++------ aep-schedule-website/src/frontend/app.rs | 15 +++++---------- aep-schedule-website/src/lib.rs | 3 +-- aep-schedule-website/src/main.rs | 2 +- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/aep-schedule-website/src/backend/fileserv.rs b/aep-schedule-website/src/backend/fileserv.rs index bde435f..904ebf2 100644 --- a/aep-schedule-website/src/backend/fileserv.rs +++ b/aep-schedule-website/src/backend/fileserv.rs @@ -21,7 +21,7 @@ pub async fn file_and_error_handler( if res.status() == StatusCode::OK { res.into_response() } else { - let handler = leptos_axum::render_app_to_stream(options.to_owned(), move || view! {<App/>}); + let handler = leptos_axum::render_app_to_stream(move || view! {<App/>}); handler(req).await.into_response() } } diff --git a/aep-schedule-website/src/backend/state.rs b/aep-schedule-website/src/backend/state.rs index 1379dc7..783d6e7 100644 --- a/aep-schedule-website/src/backend/state.rs +++ b/aep-schedule-website/src/backend/state.rs @@ -1,3 +1,4 @@ +use crate::frontend::app::shell; use crate::frontend::app::App; use aep_schedule_generator::data::courses::Courses; use aep_schedule_generator::icalendar::calendar::Calendar; @@ -10,7 +11,7 @@ use axum::{ }; use leptos::prelude::*; use leptos_axum::handle_server_fns_with_context; -use leptos_router::RouteListing; +use leptos_axum::AxumRouteListing; use std::fs::File; use std::io::BufReader; use std::sync::Arc; @@ -31,11 +32,11 @@ pub struct AppState { pub courses: Arc<RwLock<Courses>>, pub calendar: Arc<RwLock<Calendar>>, pub users_to_notify: Arc<Mutex<UsersToNotify>>, - pub routes: Vec<RouteListing>, + pub routes: Vec<AxumRouteListing>, } impl AppState { - pub async fn new(leptos_options: LeptosOptions, routes: Vec<RouteListing>) -> Self { + pub async fn new(leptos_options: LeptosOptions, routes: Vec<AxumRouteListing>) -> Self { #[cfg(not(debug_assertions))] { // Don't spam Poly when reloading the website in debug mode @@ -130,15 +131,18 @@ pub async fn leptos_routes_handler( State(app_state): State<AppState>, req: Request<AxumBody>, ) -> Response { + let state = axum::extract::State(app_state.clone()); let handler = leptos_axum::render_route_with_context( - app_state.leptos_options.clone(), app_state.routes.clone(), move || { provide_context(app_state.calendar.clone()); provide_context(app_state.courses.clone()); provide_context(app_state.users_to_notify.clone()); }, - App, + { + let leptos_options = app_state.leptos_options.clone(); + move || shell(leptos_options.clone()) + }, ); - handler(req).await.into_response() + handler(state, req).await.into_response() } diff --git a/aep-schedule-website/src/frontend/app.rs b/aep-schedule-website/src/frontend/app.rs index d0bbb14..b1648d9 100644 --- a/aep-schedule-website/src/frontend/app.rs +++ b/aep-schedule-website/src/frontend/app.rs @@ -14,12 +14,13 @@ use leptos_router::{ pub fn shell(options: LeptosOptions) -> impl IntoView { view! { <!DOCTYPE html> - <html lang="en"> + <html lang="fr"> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <AutoReload options=options.clone() /> <HydrationScripts options/> + <link rel="stylesheet" id="leptos" href="/pkg/aep-schedule-website.css"/> <MetaTags/> </head> <body> @@ -66,17 +67,11 @@ pub fn Nav() -> impl IntoView { #[component] pub fn App() -> impl IntoView { - view! { - - // injects a stylesheet into the document <head> - // id=leptos means cargo-leptos will hot-reload this stylesheet - <Stylesheet id="leptos" href="/pkg/aep-schedule-website.css"/> + provide_meta_context(); - // sets the document title - <Title text="Générateur d'horaire"/> - - // content for this welcome page + view! { <Router> + <Title text="Générateur d'horaire"/> <Nav/> <main class="h-full"> <FlatRoutes fallback=|| "Not found"> diff --git a/aep-schedule-website/src/lib.rs b/aep-schedule-website/src/lib.rs index da5d161..986ebd0 100644 --- a/aep-schedule-website/src/lib.rs +++ b/aep-schedule-website/src/lib.rs @@ -3,7 +3,6 @@ pub mod backend; pub mod frontend; cfg_if::cfg_if! { if #[cfg(feature = "hydrate")] { - use leptos::prelude::*; use wasm_bindgen::prelude::wasm_bindgen; use crate::frontend::app::App; @@ -13,6 +12,6 @@ cfg_if::cfg_if! { if #[cfg(feature = "hydrate")] { _ = console_log::init_with_level(log::Level::Debug); console_error_panic_hook::set_once(); - leptos::mount_to_body(App); + leptos::mount::mount_to_body(App); } }} diff --git a/aep-schedule-website/src/main.rs b/aep-schedule-website/src/main.rs index ae90c0a..1bb0489 100644 --- a/aep-schedule-website/src/main.rs +++ b/aep-schedule-website/src/main.rs @@ -19,7 +19,7 @@ cfg_if::cfg_if!(if #[cfg(feature = "ssr")] { // <https://github.com/leptos-rs/start-axum#executing-a-server-on-a-remote-machine-without-the-toolchain> // Alternately a file can be specified such as Some("Cargo.toml") // The file would need to be included with the executable when moved to deployment - let conf = get_configuration(None).await.unwrap(); + let conf = get_configuration(None).unwrap(); let leptos_options = conf.leptos_options; let routes = generate_route_list(App); let state = AppState::new(leptos_options.clone(), routes.clone()).await; -- GitLab From 43655f0c99cabfbc59d1bd346d163fb3d570a182 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Mon, 9 Dec 2024 23:31:04 -0500 Subject: [PATCH 10/15] refactor: remove unnecessary code --- aep-schedule-website/src/frontend/app.rs | 2 +- .../frontend/components/icons/bell_ringing.rs | 44 ++-------------- .../src/frontend/components/icons/bug.rs | 41 ++------------- .../components/icons/calendar_check.rs | 52 +++++++++---------- aep-schedule-website/src/lib.rs | 3 +- 5 files changed, 36 insertions(+), 106 deletions(-) diff --git a/aep-schedule-website/src/frontend/app.rs b/aep-schedule-website/src/frontend/app.rs index b1648d9..85d7f17 100644 --- a/aep-schedule-website/src/frontend/app.rs +++ b/aep-schedule-website/src/frontend/app.rs @@ -48,7 +48,7 @@ pub fn Nav() -> impl IntoView { <a href="https://forms.gle/u5AWgGx7vcLbCPCc7" class="sources pad-left" target="_blank"> <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Signaler un bug"</span> - <Bug weight=IconWeight::Regular size="3vh"/> + <Bug size="3vh"/> </a> <a href="https://git.step.polymtl.ca/Lemark/aep-schedule-generator-rusty" class="sources" target="_blank" ><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Sources "</span><GitlabLogo weight=IconWeight::Regular size="3vh"/></a> </nav> diff --git a/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs b/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs index 9ec0b79..a227007 100644 --- a/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs +++ b/aep-schedule-website/src/frontend/components/icons/bell_ringing.rs @@ -1,54 +1,20 @@ -use super::IconWeight; use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn BellRinging( - weight: Signal<IconWeight>, - size: TextProp, - #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, optional)] id: MaybeProp<TextProp>, + size: &'static str, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = move || { - match weight.get() { - IconWeight::Fill => view! { - <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0Z"></path> - }.into_any(), - IconWeight::Duotone => view! { - <path - d="M208,192H48a8,8,0,0,1-6.88-12C47.71,168.6,56,147.81,56,112a72,72,0,0,1,144,0c0,35.82,8.3,56.6,14.9,68A8,8,0,0,1,208,192Z" - opacity="0.2" - ></path> - <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> - }.into_any(), - IconWeight::Thin => view! { - <path d="M222.13,67.55a3.94,3.94,0,0,1-1.84.45,4,4,0,0,1-3.55-2.16,99.41,99.41,0,0,0-34.87-38.46,4,4,0,1,1,4.26-6.76,107.34,107.34,0,0,1,37.71,41.54A4,4,0,0,1,222.13,67.55ZM39.26,65.84A99.41,99.41,0,0,1,74.13,27.38a4,4,0,0,0-4.26-6.76A107.34,107.34,0,0,0,32.16,62.16a4,4,0,0,0,1.71,5.39,3.94,3.94,0,0,0,1.84.45A4,4,0,0,0,39.26,65.84ZM218.36,178A12,12,0,0,1,208,196H163.77a36,36,0,0,1-71.54,0H48A12,12,0,0,1,37.64,178C47.17,161.56,52,139.37,52,112a76,76,0,0,1,152,0C204,139.36,208.83,161.55,218.36,178ZM155.71,196H100.29a28,28,0,0,0,55.42,0Zm55.73-14C201.19,164.34,196,140.79,196,112a68,68,0,0,0-136,0c0,28.8-5.19,52.34-15.44,70a4,4,0,0,0,0,4A3.89,3.89,0,0,0,48,188H208a3.89,3.89,0,0,0,3.43-2A4,4,0,0,0,211.44,182Z"></path> - }.into_any(), - IconWeight::Bold => view! { - <path d="M225.81,74.65A11.86,11.86,0,0,1,220.3,76a12,12,0,0,1-10.67-6.47,90.1,90.1,0,0,0-32-35.38,12,12,0,1,1,12.8-20.29,115.25,115.25,0,0,1,40.54,44.62A12,12,0,0,1,225.81,74.65ZM46.37,69.53a90.1,90.1,0,0,1,32-35.38A12,12,0,1,0,65.6,13.86,115.25,115.25,0,0,0,25.06,58.48a12,12,0,0,0,5.13,16.17A11.86,11.86,0,0,0,35.7,76,12,12,0,0,0,46.37,69.53Zm173.51,98.35A20,20,0,0,1,204,200H171.81a44,44,0,0,1-87.62,0H52a20,20,0,0,1-15.91-32.12c7.17-9.33,15.73-26.62,15.88-55.94A76,76,0,0,1,204,112C204.15,141.26,212.71,158.55,219.88,167.88ZM147.6,200H108.4a20,20,0,0,0,39.2,0Zm48.74-24c-8.16-13-16.19-33.57-16.34-63.94A52,52,0,1,0,76,112c-.15,30.42-8.18,51-16.34,64Z"></path> - }.into_any(), - IconWeight::Light => view! { - <path d="M223.05,69.33A6,6,0,0,1,215,66.76,96,96,0,0,0,180.8,29.08a6,6,0,0,1,6.4-10.15,109.26,109.26,0,0,1,38.41,42.31A6,6,0,0,1,223.05,69.33ZM41,66.76A96,96,0,0,1,75.2,29.08a6,6,0,0,0-6.4-10.15A109.26,109.26,0,0,0,30.39,61.24,6,6,0,1,0,41,66.76Zm179,110.18A14,14,0,0,1,208,198h-42.5a38,38,0,0,1-75,0H48a14,14,0,0,1-12.06-21.06C45.13,161.09,50,138.63,50,112a78,78,0,0,1,156,0C206,139,210.74,160.86,220.08,176.94ZM153.29,198H102.71a26,26,0,0,0,50.58,0Zm56.42-15C199.29,165,194,141.15,194,112a66,66,0,0,0-132,0c0,29.16-5.29,53-15.71,71a2,2,0,0,0,0,2,1.9,1.9,0,0,0,1.7,1H208a1.9,1.9,0,0,0,1.7-1A2,2,0,0,0,209.71,183Z"></path> - }.into_any(), - IconWeight::Regular => view! { - <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> - }.into_any() - } - }; - - let height = size.clone(); - view! { <svg xmlns="http://www.w3.org/2000/svg" - width=move || size.get() - height=move || height.get() - fill=move || color.get() + width=size + height=size + fill="currentColor" viewBox="0 0 256 256" - id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) > - {body} + <path d="M224,71.1a8,8,0,0,1-10.78-3.42,94.13,94.13,0,0,0-33.46-36.91,8,8,0,1,1,8.54-13.54,111.46,111.46,0,0,1,39.12,43.09A8,8,0,0,1,224,71.1ZM35.71,72a8,8,0,0,0,7.1-4.32A94.13,94.13,0,0,1,76.27,30.77a8,8,0,1,0-8.54-13.54A111.46,111.46,0,0,0,28.61,60.32,8,8,0,0,0,35.71,72Zm186.1,103.94A16,16,0,0,1,208,200H167.2a40,40,0,0,1-78.4,0H48a16,16,0,0,1-13.79-24.06C43.22,160.39,48,138.28,48,112a80,80,0,0,1,160,0C208,138.27,212.78,160.38,221.81,175.94ZM150.62,200H105.38a24,24,0,0,0,45.24,0ZM208,184c-10.64-18.27-16-42.49-16-72a64,64,0,0,0-128,0c0,29.52-5.38,53.74-16,72Z"></path> </svg> } } diff --git a/aep-schedule-website/src/frontend/components/icons/bug.rs b/aep-schedule-website/src/frontend/components/icons/bug.rs index 123ec96..54868b0 100644 --- a/aep-schedule-website/src/frontend/components/icons/bug.rs +++ b/aep-schedule-website/src/frontend/components/icons/bug.rs @@ -1,51 +1,20 @@ -use super::IconWeight; use leptos::{prelude::*, text_prop::TextProp}; #[component] pub fn Bug( - #[prop(into)] weight: IconWeight, - #[prop(into)] size: TextProp, - #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, - #[prop(into, optional)] id: MaybeProp<TextProp>, + size: &'static str, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = move || { - match weight { - IconWeight::Fill => view! { - <path d="M168,92a12,12,0,1,1-12-12A12,12,0,0,1,168,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216Zm-80,0a8,8,0,0,0-16,0v64a8,8,0,0,0,16,0Zm64-32a72,72,0,0,0-144,0v8H200Z"></path> - }.into_any(), -IconWeight::Duotone => view! { - <path d="M208,128v16a80,80,0,0,1-160,0V128Z" opacity="0.2"></path> - <path d="M144,92a12,12,0,1,1,12,12A12,12,0,0,1,144,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216ZM56,120H200v-8a72,72,0,0,0-144,0Zm64,95.54V136H56v8A72.08,72.08,0,0,0,120,215.54ZM200,144v-8H136v79.54A72.08,72.08,0,0,0,200,144Z"></path> -}.into_any(), -IconWeight::Thin => view! { - <path d="M148,92a8,8,0,1,1,8,8A8,8,0,0,1,148,92Zm-48-8a8,8,0,1,0,8,8A8,8,0,0,0,100,84Zm144,44a4,4,0,0,1-4,4H212v12a83.64,83.64,0,0,1-3.87,25.2l25.47,11.13A4,4,0,0,1,232,188a4.09,4.09,0,0,1-1.6-.33l-25-10.95a84,84,0,0,1-154.72,0l-25,10.95A4.09,4.09,0,0,1,24,188a4,4,0,0,1-1.6-7.67L47.87,169.2A83.64,83.64,0,0,1,44,144V132H16a4,4,0,0,1,0-8H44V112a83.64,83.64,0,0,1,3.87-25.2L22.4,75.67a4,4,0,0,1,3.2-7.34l25,11a84,84,0,0,1,154.72,0l25-11a4,4,0,1,1,3.2,7.34L208.13,86.8A83.64,83.64,0,0,1,212,112v12h28A4,4,0,0,1,244,128ZM52,124H204V112a76,76,0,0,0-152,0Zm72,95.89V132H52v12A76.09,76.09,0,0,0,124,219.89ZM204,132H132v87.89A76.09,76.09,0,0,0,204,144Z"></path> -}.into_any(), -IconWeight::Bold => view! { - <path d="M140,88a16,16,0,1,1,16,16A16,16,0,0,1,140,88ZM100,72a16,16,0,1,0,16,16A16,16,0,0,0,100,72Zm120,72a91.84,91.84,0,0,1-2.34,20.64L236.81,173a12,12,0,0,1-9.62,22l-18-7.85a92,92,0,0,1-162.46,0l-18,7.85a12,12,0,1,1-9.62-22l19.15-8.36A91.84,91.84,0,0,1,36,144v-4H16a12,12,0,0,1,0-24H36v-4a91.84,91.84,0,0,1,2.34-20.64L19.19,83a12,12,0,0,1,9.62-22l18,7.85a92,92,0,0,1,162.46,0l18-7.85a12,12,0,1,1,9.62,22l-19.15,8.36A91.84,91.84,0,0,1,220,112v4h20a12,12,0,0,1,0,24H220ZM60,116H196v-4a68,68,0,0,0-136,0Zm56,94.92V140H60v4A68.1,68.1,0,0,0,116,210.92ZM196,144v-4H140v70.92A68.1,68.1,0,0,0,196,144Z"></path> -}.into_any(), -IconWeight::Light => view! { - <path d="M146,92a10,10,0,1,1,10,10A10,10,0,0,1,146,92ZM100,82a10,10,0,1,0,10,10A10,10,0,0,0,100,82Zm146,46a6,6,0,0,1-6,6H214v10a85.88,85.88,0,0,1-3.45,24.08L234.4,178.5a6,6,0,0,1-4.8,11l-23.23-10.15a86,86,0,0,1-156.74,0L26.4,189.5a6,6,0,1,1-4.8-11l23.85-10.42A85.88,85.88,0,0,1,42,144V134H16a6,6,0,0,1,0-12H42V112a85.88,85.88,0,0,1,3.45-24.08L21.6,77.5a6,6,0,0,1,4.8-11L49.63,76.65a86,86,0,0,1,156.74,0L229.6,66.5a6,6,0,1,1,4.8,11L210.55,87.92A85.88,85.88,0,0,1,214,112v10h26A6,6,0,0,1,246,128ZM54,122H202V112a74,74,0,0,0-148,0Zm68,95.74V134H54v10A74.09,74.09,0,0,0,122,217.74ZM202,134H134v83.74A74.09,74.09,0,0,0,202,144Z"></path> -}.into_any(), -IconWeight::Regular => view! { - <path d="M144,92a12,12,0,1,1,12,12A12,12,0,0,1,144,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216ZM56,120H200v-8a72,72,0,0,0-144,0Zm64,95.54V136H56v8A72.08,72.08,0,0,0,120,215.54ZM200,144v-8H136v79.54A72.08,72.08,0,0,0,200,144Z"></path> -}.into_any() - } - }; - - let height = size.clone(); - view! { <svg xmlns="http://www.w3.org/2000/svg" - width=move || size.get() - height=move || height.get() - fill=move || color.get() + width=size + height=size + fill="currentColor" viewBox="0 0 256 256" - id=move || id.get().map(|id| id.get()) class=move || class.get().map(|cls| cls.get()) > - {body} + <path d="M144,92a12,12,0,1,1,12,12A12,12,0,0,1,144,92ZM100,80a12,12,0,1,0,12,12A12,12,0,0,0,100,80Zm116,64A87.76,87.76,0,0,1,213,167l22.24,9.72A8,8,0,0,1,232,192a7.89,7.89,0,0,1-3.2-.67L207.38,182a88,88,0,0,1-158.76,0L27.2,191.33A7.89,7.89,0,0,1,24,192a8,8,0,0,1-3.2-15.33L43,167A87.76,87.76,0,0,1,40,144v-8H16a8,8,0,0,1,0-16H40v-8a87.76,87.76,0,0,1,3-23L20.8,79.33a8,8,0,1,1,6.4-14.66L48.62,74a88,88,0,0,1,158.76,0l21.42-9.36a8,8,0,0,1,6.4,14.66L213,89.05a87.76,87.76,0,0,1,3,23v8h24a8,8,0,0,1,0,16H216ZM56,120H200v-8a72,72,0,0,0-144,0Zm64,95.54V136H56v8A72.08,72.08,0,0,0,120,215.54ZM200,144v-8H136v79.54A72.08,72.08,0,0,0,200,144Z"></path> </svg> } } diff --git a/aep-schedule-website/src/frontend/components/icons/calendar_check.rs b/aep-schedule-website/src/frontend/components/icons/calendar_check.rs index 939e21a..880168a 100644 --- a/aep-schedule-website/src/frontend/components/icons/calendar_check.rs +++ b/aep-schedule-website/src/frontend/components/icons/calendar_check.rs @@ -1,45 +1,41 @@ use super::IconWeight; -use leptos::{prelude::*, text_prop::TextProp}; +use leptos::{either::EitherOf6, prelude::*, text_prop::TextProp}; #[component] pub fn CalendarCheck( #[prop(into)] weight: Signal<IconWeight>, - #[prop(into)] size: TextProp, + #[prop(into)] size: &'static str, #[prop(into, default = TextProp::from("currentColor"))] color: TextProp, #[prop(into, optional)] id: MaybeProp<TextProp>, #[prop(into, optional)] class: MaybeProp<TextProp>, ) -> impl IntoView { - let body = move || { - match weight.get() { - IconWeight::Fill => view! { - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM169.66,133.66l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35a8,8,0,0,1,11.32,11.32ZM48,80V48H72v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80Z"></path> - }.into_any(), - IconWeight::Duotone => view! { - <path d="M216,48V88H40V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z" opacity="0.2"></path> - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> - }.into_any(), - IconWeight::Thin => view! { - <path d="M208,36H180V24a4,4,0,0,0-8,0V36H84V24a4,4,0,0,0-8,0V36H48A12,12,0,0,0,36,48V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V48A12,12,0,0,0,208,36ZM48,44H76V56a4,4,0,0,0,8,0V44h88V56a4,4,0,0,0,8,0V44h28a4,4,0,0,1,4,4V84H44V48A4,4,0,0,1,48,44ZM208,212H48a4,4,0,0,1-4-4V92H212V208A4,4,0,0,1,208,212Zm-41.17-86.83a4,4,0,0,1,0,5.66l-48,48a4,4,0,0,1-5.66,0l-24-24a4,4,0,0,1,5.66-5.66L116,170.34l45.17-45.17A4,4,0,0,1,166.83,125.17Z"></path> - }.into_any(), - IconWeight::Bold => view! { - <path d="M208,28H188V24a12,12,0,0,0-24,0v4H92V24a12,12,0,0,0-24,0v4H48A20,20,0,0,0,28,48V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V48A20,20,0,0,0,208,28ZM68,52a12,12,0,0,0,24,0h72a12,12,0,0,0,24,0h16V76H52V52ZM52,204V100H204V204Zm120.49-84.49a12,12,0,0,1,0,17l-48,48a12,12,0,0,1-17,0l-24-24a12,12,0,0,1,17-17L116,159l39.51-39.52A12,12,0,0,1,172.49,119.51Z"></path> - }.into_any(), - IconWeight::Light => view! { - <path d="M208,34H182V24a6,6,0,0,0-12,0V34H86V24a6,6,0,0,0-12,0V34H48A14,14,0,0,0,34,48V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V48A14,14,0,0,0,208,34ZM48,46H74V56a6,6,0,0,0,12,0V46h84V56a6,6,0,0,0,12,0V46h26a2,2,0,0,1,2,2V82H46V48A2,2,0,0,1,48,46ZM208,210H48a2,2,0,0,1-2-2V94H210V208A2,2,0,0,1,208,210Zm-39.76-86.24a6,6,0,0,1,0,8.48l-48,48a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L116,167.51l43.76-43.75A6,6,0,0,1,168.24,123.76Z"></path> - }.into_any(), - IconWeight::Regular => view! { - <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> - }.into_any() - } + let body = move || match weight.get() { + IconWeight::Fill => EitherOf6::A(view! { + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM169.66,133.66l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35a8,8,0,0,1,11.32,11.32ZM48,80V48H72v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80Z"></path> + }), + IconWeight::Duotone => EitherOf6::B(view! { + <path d="M216,48V88H40V48a8,8,0,0,1,8-8H208A8,8,0,0,1,216,48Z" opacity="0.2"></path> + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> + }), + IconWeight::Thin => EitherOf6::C(view! { + <path d="M208,36H180V24a4,4,0,0,0-8,0V36H84V24a4,4,0,0,0-8,0V36H48A12,12,0,0,0,36,48V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V48A12,12,0,0,0,208,36ZM48,44H76V56a4,4,0,0,0,8,0V44h88V56a4,4,0,0,0,8,0V44h28a4,4,0,0,1,4,4V84H44V48A4,4,0,0,1,48,44ZM208,212H48a4,4,0,0,1-4-4V92H212V208A4,4,0,0,1,208,212Zm-41.17-86.83a4,4,0,0,1,0,5.66l-48,48a4,4,0,0,1-5.66,0l-24-24a4,4,0,0,1,5.66-5.66L116,170.34l45.17-45.17A4,4,0,0,1,166.83,125.17Z"></path> + }), + IconWeight::Bold => EitherOf6::D(view! { + <path d="M208,28H188V24a12,12,0,0,0-24,0v4H92V24a12,12,0,0,0-24,0v4H48A20,20,0,0,0,28,48V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V48A20,20,0,0,0,208,28ZM68,52a12,12,0,0,0,24,0h72a12,12,0,0,0,24,0h16V76H52V52ZM52,204V100H204V204Zm120.49-84.49a12,12,0,0,1,0,17l-48,48a12,12,0,0,1-17,0l-24-24a12,12,0,0,1,17-17L116,159l39.51-39.52A12,12,0,0,1,172.49,119.51Z"></path> + }), + IconWeight::Light => EitherOf6::E(view! { + <path d="M208,34H182V24a6,6,0,0,0-12,0V34H86V24a6,6,0,0,0-12,0V34H48A14,14,0,0,0,34,48V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V48A14,14,0,0,0,208,34ZM48,46H74V56a6,6,0,0,0,12,0V46h84V56a6,6,0,0,0,12,0V46h26a2,2,0,0,1,2,2V82H46V48A2,2,0,0,1,48,46ZM208,210H48a2,2,0,0,1-2-2V94H210V208A2,2,0,0,1,208,210Zm-39.76-86.24a6,6,0,0,1,0,8.48l-48,48a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L116,167.51l43.76-43.75A6,6,0,0,1,168.24,123.76Z"></path> + }), + IconWeight::Regular => EitherOf6::F(view! { + <path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-38.34-85.66a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L116,164.69l42.34-42.35A8,8,0,0,1,169.66,122.34Z"></path> + }), }; - let height = size.clone(); - view! { <svg xmlns="http://www.w3.org/2000/svg" - width=move || size.get() - height=move || height.get() + width=size + height=size fill=move || color.get() viewBox="0 0 256 256" id=move || id.get().map(|id| id.get()) diff --git a/aep-schedule-website/src/lib.rs b/aep-schedule-website/src/lib.rs index 986ebd0..9f9dba4 100644 --- a/aep-schedule-website/src/lib.rs +++ b/aep-schedule-website/src/lib.rs @@ -11,7 +11,6 @@ cfg_if::cfg_if! { if #[cfg(feature = "hydrate")] { // initializes logging using the `log` crate _ = console_log::init_with_level(log::Level::Debug); console_error_panic_hook::set_once(); - - leptos::mount::mount_to_body(App); + leptos::mount::hydrate_body(App); } }} -- GitLab From 4ea6dfa25de93634cf2c6d9c28de0bb9b7cb254e Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Tue, 10 Dec 2024 01:26:48 -0500 Subject: [PATCH 11/15] refactor: various improvement, but there is still a problem to generate --- aep-schedule-website/Cargo.lock | 900 ++++++++++-------- aep-schedule-website/Cargo.toml | 8 +- aep-schedule-website/src/backend/state.rs | 1 - .../components/options/courses_selector.rs | 22 +- .../src/frontend/components/options/form.rs | 14 +- .../components/options/optimizations.rs | 3 +- .../src/frontend/components/options/search.rs | 9 +- .../src/frontend/components/options/todo.rs | 4 +- .../src/frontend/pages/generator.rs | 38 +- .../src/frontend/state/mod.rs | 36 +- 10 files changed, 585 insertions(+), 450 deletions(-) diff --git a/aep-schedule-website/Cargo.lock b/aep-schedule-website/Cargo.lock index 54b4390..02bb657 100644 --- a/aep-schedule-website/Cargo.lock +++ b/aep-schedule-website/Cargo.lock @@ -4,19 +4,13 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -54,9 +48,9 @@ dependencies = [ "reqwest", "serde", "simple_logger", - "thiserror 1.0.63", + "thiserror 1.0.69", "tokio", - "tower 0.5.1", + "tower", "tower-http 0.5.2", "tracing", "url-escape", @@ -126,9 +120,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -147,27 +141,27 @@ dependencies = [ [[package]] name = "any_spawner" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9747eb01aed7603aba23f7c869d5d7e5d37aab9c3501aced42d8fdb786f1f6e3" +checksum = "41058deaa38c9d9dd933d6d238d825227cffa668e2839b52879f6619c63eee3b" dependencies = [ "futures", - "thiserror 1.0.63", + "thiserror 2.0.6", "tokio", "wasm-bindgen-futures", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -177,9 +171,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-compression" -version = "0.4.12" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" dependencies = [ "flate2", "futures-core", @@ -201,9 +195,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", @@ -248,9 +242,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" @@ -280,9 +274,9 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", - "tower 0.5.1", + "tower", "tower-layer", "tower-service", "tracing", @@ -303,7 +297,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -322,17 +316,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", + "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -355,9 +349,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "binstring" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0d60973d9320722cb1206f412740e162a33b8547ea8d6be75d7cff237c7a85" +checksum = "ed79c2a8151273c70956b5e3cdfdc1ff6c1a8b9779ba59c6807d281b32ee2f86" [[package]] name = "bitflags" @@ -399,9 +393,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "camino" @@ -420,9 +414,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.14" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] @@ -435,9 +429,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -470,9 +464,9 @@ dependencies = [ [[package]] name = "coarsetime" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b3839cf01bb7960114be3ccf2340f541b6d0c81f8690b007b2b39f750f7e5d" +checksum = "4252bf230cb600c19826a575b31c8c9c84c6f11acfab6dfcad2e941b10b6f8e2" dependencies = [ "libc", "wasix", @@ -487,7 +481,7 @@ checksum = "5d3ad3122b0001c7f140cf4d605ef9a9e2c24d96ab0b4fb4347b76de2425f445" dependencies = [ "serde", "serde_json", - "thiserror 1.0.63", + "thiserror 1.0.69", ] [[package]] @@ -571,18 +565,18 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -597,9 +591,9 @@ checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "convert_case" @@ -628,9 +622,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -675,9 +669,9 @@ dependencies = [ [[package]] name = "ct-codecs" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" +checksum = "b916ba8ce9e4182696896f015e8a5ae6081b305f74690baa8465e35f5a142ea4" [[package]] name = "ctr" @@ -745,6 +739,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "drain_filter_polyfill" version = "0.1.3" @@ -794,9 +799,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "either_of" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6e22feb4d5cacf9f2c64902a1c35ef0f2d766e42db316a98b93992bbce669cb" +checksum = "0d1e2e7b8b6deaf1ae68f1d8796dec8732cff85d27fdbf4bc4460145a067ed0b" dependencies = [ "pin-project-lite", ] @@ -824,9 +829,9 @@ dependencies = [ [[package]] name = "email-encoding" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60d1d33cdaede7e24091f039632eb5d3c7469fe5b066a985281a34fc70fa317f" +checksum = "ea3d894bbbab314476b265f9b2d46bf24b123a36dd0e96b06a1b49545b9d9dcc" dependencies = [ "base64", "memchr", @@ -840,9 +845,9 @@ checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -855,12 +860,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -876,9 +881,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ "event-listener", "pin-project-lite", @@ -886,9 +891,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" @@ -902,12 +907,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -1066,9 +1071,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gloo-net" @@ -1085,7 +1090,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror 1.0.63", + "thiserror 1.0.69", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -1123,9 +1128,9 @@ checksum = "493913a18c0d7bebb75127a26a432162c59edbe06f6cf712001e3e769345e8b5" [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -1152,9 +1157,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hermit-abi" @@ -1182,24 +1187,24 @@ dependencies = [ [[package]] name = "hmac-sha1-compact" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9d405ec732fa3fcde87264e54a32a84956a377b3e3107de96e59b798c84a7" +checksum = "18492c9f6f9a560e0d346369b665ad2bdbc89fa9bceca75796584e79042694c3" [[package]] name = "hmac-sha256" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3688e69b38018fec1557254f64c8dc2cc8ec502890182f395dbb0aa997aa5735" +checksum = "4a8575493d277c9092b988c780c94737fb9fd8651a1001e16bee3eccfc1baedb" dependencies = [ "digest", ] [[package]] name = "hmac-sha512" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ce1f4656bae589a3fab938f9f09bf58645b7ed01a2c5f8a3c238e01a4ef78a" +checksum = "b0b3a0f572aa8389d325f5852b9e0a333a15b0f86ecccbb3fdb6e97cd86dc67c" dependencies = [ "digest", ] @@ -1226,9 +1231,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -1260,15 +1265,15 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1278,9 +1283,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hydration_context" -version = "0.2.0-rc2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e578296c79066cdf7325259d8259b48adc311e324beecd801c43d953532c51b" +checksum = "ef13071fe13b55c85fe2b70246d2e3b49d2c6a764fd3e0edaf262cc385ff1854" dependencies = [ "futures", "js-sys", @@ -1315,9 +1320,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http", @@ -1348,9 +1353,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", @@ -1361,16 +1366,15 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower 0.4.13", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1400,24 +1404,153 @@ dependencies = [ "uuid", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -1443,9 +1576,9 @@ checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "iso8601" @@ -1467,9 +1600,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" @@ -1482,9 +1615,9 @@ dependencies = [ [[package]] name = "jwt-simple" -version = "0.12.9" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094661f5aad510abe2658bff20409e89046b753d9dc2d4007f5c100b6d982ba0" +checksum = "b00e03c08ce71da10a3ad9267b963c03fc4234a56713d87648547b3fdda872a6" dependencies = [ "anyhow", "binstring", @@ -1502,15 +1635,15 @@ dependencies = [ "serde", "serde_json", "superboring", - "thiserror 1.0.63", + "thiserror 2.0.6", "zeroize", ] [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -1531,9 +1664,9 @@ dependencies = [ [[package]] name = "leptos" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc41e5764d7476efb929db94c1039752ccde5bea2ad40fddaaeeb9b94493fb0d" +checksum = "ba5046c590aea121f6ad5e71fcb75453a933425d39527b9a3b1b295235afc8df" dependencies = [ "any_spawner", "base64", @@ -1558,7 +1691,7 @@ dependencies = [ "server_fn", "slotmap", "tachys", - "thiserror 2.0.3", + "thiserror 2.0.6", "throw_error", "typed-builder", "typed-builder-macro", @@ -1568,9 +1701,9 @@ dependencies = [ [[package]] name = "leptos_axum" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a7318603b14939a7332555ce8fd24a043047780dc6c9820359472ec4db6251" +checksum = "7b0d388392939f629c45b8c7bcc83997cb6c6026813b57f50953651ad5be63d8" dependencies = [ "any_spawner", "axum", @@ -1586,28 +1719,28 @@ dependencies = [ "parking_lot", "server_fn", "tokio", - "tower 0.5.1", + "tower", "tower-http 0.6.2", ] [[package]] name = "leptos_config" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe8f7f58ee40b2c0d7e1f0abdbf51ffd2343d281b3f16c1854c0218c152fbad8" +checksum = "5e2d64c43e2554108c26da3127f8384d92ca76c6f0b7288d1c09c8cc68152064" dependencies = [ "config", "regex", "serde", - "thiserror 2.0.3", + "thiserror 2.0.6", "typed-builder", ] [[package]] name = "leptos_dom" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dccedefe9054b9ca09e027801557dc82cad64cb1f1a8061b114e7f6203bbe51" +checksum = "6c15aca81dc2edd040b51c46734f65c6f36e6ba8a31347c1354c94b958044ae0" dependencies = [ "js-sys", "or_poisoned", @@ -1620,9 +1753,9 @@ dependencies = [ [[package]] name = "leptos_hot_reload" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754d861dbdaf20b6da328112b68e1b2ea2da9a157aef748f53b15fd118972b85" +checksum = "0445f3a62696d2d66bef288911af34405718880b4b8dd6c5cfb7751fd8ffcc6b" dependencies = [ "anyhow", "camino", @@ -1638,9 +1771,9 @@ dependencies = [ [[package]] name = "leptos_integration_utils" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30224324686ef508bc4a08fcfc16451410823b7d11b83325d2444221880bbbaa" +checksum = "d293a2f64a558d4ca10ef01125d055134f3582f27c407102c4259bb54ca8b55b" dependencies = [ "futures", "hydration_context", @@ -1653,9 +1786,9 @@ dependencies = [ [[package]] name = "leptos_macro" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c592d8e91148c73ee562f6d4b867d84d1995a5adb10d5a723f538b3dc173dfc" +checksum = "92f690c955274f1722ee6c66463ace79301d53a8c2bf7f6e4e61b978ca239e20" dependencies = [ "attribute-derive", "cfg-if", @@ -1675,9 +1808,9 @@ dependencies = [ [[package]] name = "leptos_meta" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d95aec94d2c28120fe702182ec83e5402b9ad2c6fccaf3dbb98d0d94bf9f908" +checksum = "7c651d788bbbf1c57ee95dd3835f9d433b85a409b6256f338c3c7146eb8b7f53" dependencies = [ "futures", "indexmap", @@ -1691,9 +1824,9 @@ dependencies = [ [[package]] name = "leptos_router" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123f2c0df5b3fd3025d1c26bc0dce1abd236409d9f031112ab5a0f871cfa6cbb" +checksum = "32a4f1784486ebf36805dac22faee21e3e610aa64b6662a7386f065eeec27ae8" dependencies = [ "any_spawner", "either_of", @@ -1708,7 +1841,7 @@ dependencies = [ "reactive_graph", "send_wrapper", "tachys", - "thiserror 2.0.3", + "thiserror 2.0.6", "url", "wasm-bindgen", "web-sys", @@ -1716,9 +1849,9 @@ dependencies = [ [[package]] name = "leptos_router_macro" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84e0d92a7d6973682f02539b8de1f37651e72f557b1fd3f2d55460662669926" +checksum = "eee7ecef3f1c69b51864190c564e4873d84f200e44efb37934208f9525f02a5f" dependencies = [ "proc-macro-error2", "proc-macro2", @@ -1727,9 +1860,9 @@ dependencies = [ [[package]] name = "leptos_server" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1387314dcb7f9547394a61b0cb41cdbd09e6c5dd5e154e304123f3d9b5b747b" +checksum = "93450589df3b3e398c7f5ea64d8f1c8369b1ba9b90e1f70f6cb996b8d443ca3e" dependencies = [ "any_spawner", "base64", @@ -1747,9 +1880,9 @@ dependencies = [ [[package]] name = "lettre" -version = "0.11.7" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a62049a808f1c4e2356a2a380bd5f2aca3b011b0b482cf3b914ba1731426969" +checksum = "ab4c9a167ff73df98a5ecc07e8bf5ce90b583665da3d1762eb1f775ad4d0d6f5" dependencies = [ "async-trait", "base64", @@ -1775,15 +1908,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linear-map" @@ -1797,6 +1930,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -1870,15 +2009,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -1890,11 +2020,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", @@ -1936,9 +2065,9 @@ dependencies = [ [[package]] name = "next_tuple" -version = "0.1.0-rc2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6989c5af5a391cdc1c25aad10c6fb881b6e7ebd8df7c6fb29188acb5cba576" +checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28" [[package]] name = "nom" @@ -2024,9 +2153,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -2038,7 +2167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64b94982fe39a861561cf67ff17a7849f2cedadbbad960a797634032b7abb998" dependencies = [ "serde", - "thiserror 1.0.63", + "thiserror 1.0.69", ] [[package]] @@ -2055,9 +2184,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags", "cfg-if", @@ -2087,9 +2216,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -2164,9 +2293,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pem-rfc7468" @@ -2185,18 +2314,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", @@ -2238,9 +2367,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "polyval" @@ -2368,9 +2497,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.21" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" dependencies = [ "cc", ] @@ -2444,9 +2573,9 @@ dependencies = [ [[package]] name = "reactive_graph" -version = "0.1.0-rc2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49131fcf9733a991f3485f9a0d0c9b9f65f55df4bb9f9d37203d1f82efa9513c" +checksum = "c27f54685c1416af1f323a0c40e71cbdae281a1ebc623591790d367222d0ac65" dependencies = [ "any_spawner", "async-lock", @@ -2459,15 +2588,15 @@ dependencies = [ "send_wrapper", "serde", "slotmap", - "thiserror 2.0.3", + "thiserror 2.0.6", "web-sys", ] [[package]] name = "reactive_stores" -version = "0.1.0-rc2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e722a72d10534f7613291bd2ef44cd2473ad70b2aa965d4bb7b940afb6f7257" +checksum = "efe3f866edc7647e19a68a229a2e5cc9730549836d722eeaa073116f2b07966e" dependencies = [ "guardian", "itertools", @@ -2480,9 +2609,9 @@ dependencies = [ [[package]] name = "reactive_stores_macro" -version = "0.1.0-rc2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37fc52b98f16d437cdf5541cf60f661596b6e84a708e02b216a7bf864fe699b" +checksum = "4d86e4f08f361b05d11422398cef4bc4cf356f2fdd2f06a96646b0e9cd902226" dependencies = [ "convert_case", "proc-macro-error2", @@ -2493,9 +2622,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] @@ -2531,9 +2660,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.7" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64", "bytes", @@ -2560,7 +2689,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "system-configuration", "tokio", "tokio-native-tls", @@ -2599,9 +2728,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", "digest", @@ -2630,7 +2759,7 @@ dependencies = [ "quote", "syn", "syn_derive", - "thiserror 1.0.63", + "thiserror 1.0.69", ] [[package]] @@ -2641,28 +2770,28 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "once_cell", "rustls-pki-types", @@ -2673,25 +2802,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -2700,9 +2828,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -2721,11 +2849,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2763,9 +2891,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -2782,18 +2910,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -2802,9 +2930,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -2830,14 +2958,14 @@ checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6" dependencies = [ "percent-encoding", "serde", - "thiserror 1.0.63", + "thiserror 1.0.69", ] [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -2856,9 +2984,9 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed94ec81d1b9ef2b28325bcf715461d861e90f41d249b70b561c6eefcb96afe" +checksum = "033cb8014aa86a7ce0c6ee58d23dce1a078b2e320dc6c53bb439663993199b1f" dependencies = [ "axum", "bytes", @@ -2878,9 +3006,9 @@ dependencies = [ "serde_json", "serde_qs", "server_fn_macro_default", - "thiserror 2.0.3", + "thiserror 2.0.6", "throw_error", - "tower 0.5.1", + "tower", "tower-layer", "url", "wasm-bindgen", @@ -2892,9 +3020,9 @@ dependencies = [ [[package]] name = "server_fn_macro" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7e77dd4f15d19a65019d24700963e40294b5a30c42c32bce2e532fbfe00b49" +checksum = "0249e8a55ca464a1e69f02a95d562f2c65e92e301093a02ebf15d21f68f2a99e" dependencies = [ "const_format", "convert_case", @@ -2906,9 +3034,9 @@ dependencies = [ [[package]] name = "server_fn_macro_default" -version = "0.7.0-rc2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295a3c3d01be1cf17d0c8b25a48b963a747f6ccdba0f62f657e8df37df4afaac" +checksum = "91c54a6d43cd0f3d2bdf0c85b6119f378b6b89d528159af9cde77f229faeecbc" dependencies = [ "server_fn_macro", "syn", @@ -2988,9 +3116,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3012,17 +3140,23 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "stacker" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a5daa25ea337c85ed954c0496e3bdd2c7308cc3b24cf7b50d04876654c579f" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "windows-sys 0.36.1", + "windows-sys 0.59.0", ] [[package]] @@ -3039,9 +3173,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "superboring" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbde97f499e51ef384f585dc8f8fb6a9c3a71b274b8d12469b516758e6540607" +checksum = "515cce34a781d7250b8a65706e0f2a5b99236ea605cb235d4baed6685820478f" dependencies = [ "getrandom", "hmac-sha256", @@ -3052,9 +3186,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -3081,13 +3215,24 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "system-configuration" version = "0.6.1" @@ -3111,9 +3256,9 @@ dependencies = [ [[package]] name = "tachys" -version = "0.1.0-rc2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231b9e7ce516683c062dd2c8e4d30b81ae8d9a6d05f1e2a9c898e0b84ad728fe" +checksum = "8be68dfd4abf192e11a1bdd484239daa84ffa6fcd27c25cf4f011b2b0fb27ddb" dependencies = [ "any_spawner", "const_str_slice_concat", @@ -3143,9 +3288,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -3156,27 +3301,27 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.63", + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "thiserror-impl 2.0.3", + "thiserror-impl 2.0.6", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -3185,9 +3330,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", @@ -3196,18 +3341,18 @@ dependencies = [ [[package]] name = "throw_error" -version = "0.2.0-rc2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0240909e3ad4ed2dab72b2861fc9a7930110c1d3a9a0a32c6dee0a747591d10a" +checksum = "e4ef8bf264c6ae02a065a4a16553283f0656bd6266fc1fcb09fd2e6b5e91427b" dependencies = [ "pin-project-lite", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -3228,34 +3373,29 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -3292,20 +3432,19 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -3337,9 +3476,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -3348,21 +3487,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - [[package]] name = "tower" version = "0.5.1" @@ -3445,9 +3569,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -3457,9 +3581,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -3468,9 +3592,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -3509,45 +3633,27 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -3567,9 +3673,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -3585,12 +3691,24 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.11.0" @@ -3812,19 +3930,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -3895,12 +4000,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3913,12 +4012,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3937,12 +4030,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3955,12 +4042,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3985,12 +4066,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -4005,13 +4080,25 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xxhash-rust" version = "0.8.12" @@ -4024,6 +4111,30 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -4045,8 +4156,51 @@ dependencies = [ "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/aep-schedule-website/Cargo.toml b/aep-schedule-website/Cargo.toml index 05af712..b8aa580 100644 --- a/aep-schedule-website/Cargo.toml +++ b/aep-schedule-website/Cargo.toml @@ -11,10 +11,10 @@ axum = { version = "0.7", optional = true, features = ["macros"] } console_error_panic_hook = "0.1" console_log = "1" cfg-if = "1" -leptos = { version = "0.7.0-rc2", features = ["nightly"] } -leptos_router = { version = "0.7.0-rc2" } -leptos_meta = { version = "0.7.0-rc2" } -leptos_axum = { version = "0.7.0-rc2", optional = true } +leptos = { version = "0.7.0", features = ["nightly"] } +leptos_router = { version = "0.7.0" } +leptos_meta = { version = "0.7.0" } +leptos_axum = { version = "0.7.0", optional = true } log = "0.4" rand = { version = "0.8", optional = true } simple_logger = "5" diff --git a/aep-schedule-website/src/backend/state.rs b/aep-schedule-website/src/backend/state.rs index 783d6e7..4a04b8e 100644 --- a/aep-schedule-website/src/backend/state.rs +++ b/aep-schedule-website/src/backend/state.rs @@ -1,5 +1,4 @@ use crate::frontend::app::shell; -use crate::frontend::app::App; use aep_schedule_generator::data::courses::Courses; use aep_schedule_generator::icalendar::calendar::Calendar; use axum::{ diff --git a/aep-schedule-website/src/frontend/components/options/courses_selector.rs b/aep-schedule-website/src/frontend/components/options/courses_selector.rs index c08030e..41f98aa 100644 --- a/aep-schedule-website/src/frontend/components/options/courses_selector.rs +++ b/aep-schedule-website/src/frontend/components/options/courses_selector.rs @@ -151,20 +151,21 @@ where } #[component] -pub fn CoursesSelector<F>(state: OptionState, submit: F) -> impl IntoView +pub fn CoursesSelector<F>(submit: F) -> impl IntoView where F: Fn() + Copy + 'static + Send, { let (active_tab, set_active_tab) = signal("".to_string()); - let action_courses = state.action_courses; + let state = OptionState::from_context(); + let courses = state.courses; view! { <Await future=get_courses() - let:courses + let:all_courses > - <SearchCourse courses=courses.clone() action_courses set_active_tab/> + <SearchCourse set_active_tab all_courses=all_courses.clone()/> </Await> <div class="flex w-full flex-wrap gap-1"> <button class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" class=("opacity-75", move || active_tab.get() != "") id="personal" on:pointerdown={ @@ -174,7 +175,7 @@ where {"Horaire personnel"} </button> <For - each=move || {action_courses.value().get().unwrap_or_default()} + each=move || {courses.get()} key=|c| c.sigle.clone() children=move |course| { let sigle = course.sigle.to_string(); @@ -188,15 +189,10 @@ where move |_| set_active_tab.set(sigle.clone()) }> {sigle2} - <button class="close" on:pointerdown={ + <button class="close" on:click={ let sigle = sigle.clone(); move |_| { - action_courses.value().update(|courses| { - if let Some(courses) = courses { - courses.retain(|c| c.sigle.as_str() != sigle); - }} - ); - state.stored_courses.update_value(|courses| { + state.courses.update(|courses| { courses.retain(|c| c.sigle.as_str() != sigle); }); submit(); @@ -212,7 +208,7 @@ where <PersonalTimeSelector week=state.week submit></PersonalTimeSelector> </Tab> <For - each=move || {action_courses.value().get().unwrap_or_default()} + each=move || {courses.get()} key=|c| c.sigle.clone() let:course > diff --git a/aep-schedule-website/src/frontend/components/options/form.rs b/aep-schedule-website/src/frontend/components/options/form.rs index e88fb50..6e6c027 100644 --- a/aep-schedule-website/src/frontend/components/options/form.rs +++ b/aep-schedule-website/src/frontend/components/options/form.rs @@ -10,9 +10,9 @@ use leptos::prelude::*; #[component] pub fn OptionsForms() -> impl IntoView { - let state = OptionState::from_context(); - let first_generation_done: FirstGenerationDone = use_context().unwrap(); + + let state = OptionState::from_context(); let submit = move || { state.validate(); if !first_generation_done.0.get() || state.step.get() < 5 { @@ -21,12 +21,6 @@ pub fn OptionsForms() -> impl IntoView { state.generate(); }; - Effect::new(move |_| { - state.action_courses.pending().track(); - submit(); - async move {} - }); - let submit_mobile = move |_| { state.validate(); if state.step.get() < 5 { @@ -37,10 +31,10 @@ pub fn OptionsForms() -> impl IntoView { }; view! { - <CoursesSelector state=state submit/> + <CoursesSelector submit/> <span class="grow"></span> <NumberInput value=state.max_nb_conflicts max=127 label="Nombre de période de cours en conflits maximum: " submit/> - <SelectOptimizations state=state submit/> + <SelectOptimizations submit/> <button on:pointerdown=submit_mobile class="lg:hidden select-none rounded-lg bg-amber-500 py-2 text-xl px-4 w-64 self-center text-center align-middle text-black shadow-md shadow-amber-500/20 transition-all hover:shadow-lg hover:shadow-amber-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none">"Générer les horaires"</button> } } diff --git a/aep-schedule-website/src/frontend/components/options/optimizations.rs b/aep-schedule-website/src/frontend/components/options/optimizations.rs index f0541af..918ac1e 100644 --- a/aep-schedule-website/src/frontend/components/options/optimizations.rs +++ b/aep-schedule-website/src/frontend/components/options/optimizations.rs @@ -18,10 +18,11 @@ fn weight(input: u8) -> IconWeight { } #[component] -pub fn SelectOptimizations<F>(state: OptionState, submit: F) -> impl IntoView +pub fn SelectOptimizations<F>(submit: F) -> impl IntoView where F: Fn() + Copy + 'static, { + let state = OptionState::from_context(); let weight_house = Memo::new(move |_| weight(state.day_off.get())); let weight_early = Memo::new(move |_| weight((-cmp::min(0, state.morning.get())) as u8)); let weight_morning = Memo::new(move |_| weight(cmp::max(0, state.morning.get()) as u8)); diff --git a/aep-schedule-website/src/frontend/components/options/search.rs b/aep-schedule-website/src/frontend/components/options/search.rs index 9980493..ab8f109 100644 --- a/aep-schedule-website/src/frontend/components/options/search.rs +++ b/aep-schedule-website/src/frontend/components/options/search.rs @@ -1,24 +1,25 @@ use crate::frontend::{ components::common::autocomplete::{AutoComplete, AutoCompleteOption}, - state::reactive_course::ReactiveCourse, + state::OptionState, }; use aep_schedule_generator::data::course::CourseName; use leptos::prelude::*; #[component] pub fn SearchCourse( - courses: Result<Vec<CourseName>, ServerFnError>, + all_courses: Result<Vec<CourseName>, ServerFnError>, set_active_tab: WriteSignal<String>, - action_courses: Action<String, Vec<ReactiveCourse>>, ) -> impl IntoView { - let Ok(courses) = courses else { + let Ok(courses) = all_courses else { return None; }; + let state = OptionState::from_context(); let courses = courses .into_iter() .map(|c| AutoCompleteOption::new(c.sigle.clone(), c.sigle + " - " + &c.name)) .collect(); + let action_courses = state.action_courses; let on_submit = move |sigle: String| { set_active_tab(sigle.clone()); action_courses.dispatch(sigle); diff --git a/aep-schedule-website/src/frontend/components/options/todo.rs b/aep-schedule-website/src/frontend/components/options/todo.rs index 38c51e0..5f15b8c 100644 --- a/aep-schedule-website/src/frontend/components/options/todo.rs +++ b/aep-schedule-website/src/frontend/components/options/todo.rs @@ -46,15 +46,15 @@ pub fn Step( #[component] pub fn Todo() -> impl IntoView { - let state = OptionState::from_context(); let first_generation_done: FirstGenerationDone = use_context().unwrap(); + let state = OptionState::from_context(); let submit = move |_| { first_generation_done.0.set(true); state.generate(); }; - let step = state.step; + let step: RwSignal<u8> = state.step; let disab = move || { let step = step.get(); diff --git a/aep-schedule-website/src/frontend/pages/generator.rs b/aep-schedule-website/src/frontend/pages/generator.rs index bdba427..b1504b2 100644 --- a/aep-schedule-website/src/frontend/pages/generator.rs +++ b/aep-schedule-website/src/frontend/pages/generator.rs @@ -22,34 +22,34 @@ pub fn GeneratorPage() -> impl IntoView { let first_generation_done = RwSignal::new(false); let (modal, set_modal) = signal(None); let state = OptionState::default(); - + let hide = state.hide; provide_context(state); provide_context(SetModal(set_modal)); provide_context(FirstGenerationDone(first_generation_done)); view! { - <aside class="left-panel" class=("hide-left-panel", state.hide)> + <aside class="left-panel" class=("hide-left-panel", hide)> <OptionsForms/> </aside> - <section class="right-panel" on:scroll=move |ev| { - use web_sys::wasm_bindgen::JsCast; - - let target = ev - .target() - .unwrap() - .dyn_into::<web_sys::Element>() - .unwrap(); - let scroll_top = target.scroll_top() as f64; - let client_height = target.client_height() as f64; - let scroll_height = target.scroll_height() as f64; - if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { - state.regenerate(); - } - - }> + <section class="right-panel" + // on:scroll=move |ev| { + // use web_sys::wasm_bindgen::JsCast; + // let target = ev + // .target() + // .unwrap() + // .dyn_into::<web_sys::Element>() + // .unwrap(); + // let scroll_top = target.scroll_top() as f64; + // let client_height = target.client_height() as f64; + // let scroll_height = target.scroll_height() as f64; + // if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { + // state.regenerate(); + // } + + > <SchedulesComponent/> </section> <Notifications modal set_modal/> - <button on:pointerdown=move |_| {state.hide.set(false)} id="go-back"><CaretDoubleRight weight=IconWeight::Regular size="3vh"/></button> + <button on:pointerdown=move |_| {hide.set(false)} id="go-back"><CaretDoubleRight weight=IconWeight::Regular size="3vh"/></button> } } diff --git a/aep-schedule-website/src/frontend/state/mod.rs b/aep-schedule-website/src/frontend/state/mod.rs index 3657e6b..c51a6e6 100644 --- a/aep-schedule-website/src/frontend/state/mod.rs +++ b/aep-schedule-website/src/frontend/state/mod.rs @@ -13,8 +13,8 @@ pub mod reactive_course; #[derive(Copy, Clone)] pub struct OptionState { - pub stored_courses: StoredValue<Vec<ReactiveCourse>>, - pub action_courses: Action<String, Vec<ReactiveCourse>>, + pub courses: RwSignal<Vec<ReactiveCourse>>, + pub action_courses: Action<String, ()>, pub week: [RwSignal<u64>; 5], pub max_nb_conflicts: RwSignal<u8>, pub day_off: RwSignal<u8>, @@ -33,8 +33,8 @@ impl OptionState { use_context().unwrap() } - pub fn validate(self) { - let mut options: SchedulesOptions = (&self).into(); + pub fn validate(&self) { + let mut options: SchedulesOptions = self.into(); if options.courses_to_take.is_empty() { self.step.set(1); return; @@ -100,26 +100,23 @@ impl OptionState { impl Default for OptionState { fn default() -> Self { - let stored_courses: StoredValue<Vec<ReactiveCourse>> = StoredValue::new(vec![]); + let courses: RwSignal<Vec<ReactiveCourse>> = RwSignal::new(vec![]); let action_courses = Action::new(move |sigle: &String| { let sigle = sigle.clone(); async move { - if let Ok(c) = get_course(sigle).await { - if !stored_courses - .get_value() - .iter() - .any(|react_c| react_c.sigle == c.sigle) - { - stored_courses.update_value(|courses| courses.push(c.into())); - } + if let Ok(c) = get_course(sigle.clone()).await { + courses.update(|courses| { + if !courses.iter().any(|c| c.sigle == sigle) { + courses.push(c.into()); + } + }); } - stored_courses.get_value() } }); Self { - stored_courses, + courses, action_courses, max_nb_conflicts: RwSignal::new(0), week: std::array::from_fn(|_i| RwSignal::new(0)), @@ -138,14 +135,7 @@ impl Default for OptionState { impl From<&OptionState> for SchedulesOptions { fn from(state: &OptionState) -> Self { - let courses_to_take = state - .action_courses - .value() - .get() - .unwrap_or_default() - .into_iter() - .map(|c| c.into()) - .collect(); + let courses_to_take = state.courses.get().into_iter().map(|c| c.into()).collect(); let mut max_size = 8; state .max_size -- GitLab From b4e8a1353a0fe9a427095b964d41d70337f613d0 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Tue, 10 Dec 2024 17:40:04 -0500 Subject: [PATCH 12/15] refactor: format all files --- aep-schedule-website/src/backend/fileserv.rs | 2 +- aep-schedule-website/src/frontend/app.rs | 89 ++++-- .../components/common/autocomplete.rs | 52 ++-- .../components/common/number_input.rs | 47 +++- .../frontend/components/common/schedule.rs | 43 ++- .../src/frontend/components/common/tab.rs | 5 +- .../src/frontend/components/icons/download.rs | 2 +- .../src/frontend/components/notifications.rs | 20 +- .../components/options/courses_selector.rs | 261 +++++++++++------- .../src/frontend/components/options/form.rs | 18 +- .../components/options/optimizations.rs | 52 ++-- .../frontend/components/options/personal.rs | 72 ++--- .../src/frontend/components/options/search.rs | 7 +- .../src/frontend/components/options/todo.rs | 128 ++++++--- .../src/frontend/components/schedule.rs | 62 +++-- .../src/frontend/components/schedules.rs | 58 ++-- .../src/frontend/pages/apropos.rs | 39 ++- .../src/frontend/pages/classroom.rs | 48 +++- .../src/frontend/pages/generator.rs | 39 +-- 19 files changed, 693 insertions(+), 351 deletions(-) diff --git a/aep-schedule-website/src/backend/fileserv.rs b/aep-schedule-website/src/backend/fileserv.rs index 904ebf2..9a0424e 100644 --- a/aep-schedule-website/src/backend/fileserv.rs +++ b/aep-schedule-website/src/backend/fileserv.rs @@ -21,7 +21,7 @@ pub async fn file_and_error_handler( if res.status() == StatusCode::OK { res.into_response() } else { - let handler = leptos_axum::render_app_to_stream(move || view! {<App/>}); + let handler = leptos_axum::render_app_to_stream(move || view! { <App /> }); handler(req).await.into_response() } } diff --git a/aep-schedule-website/src/frontend/app.rs b/aep-schedule-website/src/frontend/app.rs index 85d7f17..961fe02 100644 --- a/aep-schedule-website/src/frontend/app.rs +++ b/aep-schedule-website/src/frontend/app.rs @@ -16,15 +16,15 @@ pub fn shell(options: LeptosOptions) -> impl IntoView { <!DOCTYPE html> <html lang="fr"> <head> - <meta charset="utf-8"/> - <meta name="viewport" content="width=device-width, initial-scale=1"/> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> <AutoReload options=options.clone() /> - <HydrationScripts options/> - <link rel="stylesheet" id="leptos" href="/pkg/aep-schedule-website.css"/> - <MetaTags/> + <HydrationScripts options /> + <link rel="stylesheet" id="leptos" href="/pkg/aep-schedule-website.css" /> + <MetaTags /> </head> <body> - <App/> + <App /> </body> </html> } @@ -37,26 +37,61 @@ pub fn Nav() -> impl IntoView { view! { <header> <nav class=("active", is_active) class="flex-wrap overflow-x-hidden"> - <span class="text-2xl font-semibold leading-none font-sans tracking-tight">"Générateur d'horaire de l'AEP" - <span class="text-amber-600">"v2"</span> + <span class="text-2xl font-semibold leading-none font-sans tracking-tight"> + "Générateur d'horaire de l'AEP" <span class="text-amber-600">"v2"</span> </span> - <span class="bg-red-200 text-red-800 text-lg font-sans tracking-tight font-medium me-2 px-2.5 py-0.5 rounded-full shrink">"Beta - "<a class="text-gray-800" href="https://horaires.aep.polymtl.ca/">"Retourner à l'ancien générateur"</a></span> - <A href="/"><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Générateur d'horaire"</span></A> - <A href="/local"><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Horaire d'un local"</span></A> - <A href="/apropos"><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"À propos"</span></A> - + <span class="bg-red-200 text-red-800 text-lg font-sans tracking-tight font-medium me-2 px-2.5 py-0.5 rounded-full shrink"> + "Beta - "<a class="text-gray-800" href="https://horaires.aep.polymtl.ca/"> + "Retourner à l'ancien générateur" + </a> + </span> + <A href="/"> + <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight"> + "Générateur d'horaire" + </span> + </A> + <A href="/local"> + <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight"> + "Horaire d'un local" + </span> + </A> + <A href="/apropos"> + <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight"> + "À propos" + </span> + </A> - <a href="https://forms.gle/u5AWgGx7vcLbCPCc7" class="sources pad-left" target="_blank"> - <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Signaler un bug"</span> - <Bug size="3vh"/> + <a + href="https://forms.gle/u5AWgGx7vcLbCPCc7" + class="sources pad-left" + target="_blank" + > + <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight"> + "Signaler un bug" + </span> + <Bug size="3vh" /> + </a> + <a + href="https://git.step.polymtl.ca/Lemark/aep-schedule-generator-rusty" + class="sources" + target="_blank" + > + <span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight"> + "Sources " + </span> + <GitlabLogo weight=IconWeight::Regular size="3vh" /> </a> - <a href="https://git.step.polymtl.ca/Lemark/aep-schedule-generator-rusty" class="sources" target="_blank" ><span class="rounded-md font-medium text-gray-700 text-lg font-sans tracking-tight">"Sources "</span><GitlabLogo weight=IconWeight::Regular size="3vh"/></a> </nav> - <div class=("active", is_active) class="hamburger" on:pointerdown=move |_| { - set_active.update(|active| { - *active = !*active; - }); - }> + <div + class=("active", is_active) + class="hamburger" + on:pointerdown=move |_| { + set_active + .update(|active| { + *active = !*active; + }); + } + > <span class="hamburger-bar"></span> <span class="hamburger-bar"></span> <span class="hamburger-bar"></span> @@ -71,13 +106,13 @@ pub fn App() -> impl IntoView { view! { <Router> - <Title text="Générateur d'horaire"/> - <Nav/> + <Title text="Générateur d'horaire" /> + <Nav /> <main class="h-full"> <FlatRoutes fallback=|| "Not found"> - <Route path=StaticSegment("/") view=GeneratorPage/> - <Route path=StaticSegment("/apropos") view=HomePage/> - <Route path=StaticSegment("/local") view=ClassRoomComponent/> + <Route path=StaticSegment("/") view=GeneratorPage /> + <Route path=StaticSegment("/apropos") view=HomePage /> + <Route path=StaticSegment("/local") view=ClassRoomComponent /> </FlatRoutes> </main> </Router> diff --git a/aep-schedule-website/src/frontend/components/common/autocomplete.rs b/aep-schedule-website/src/frontend/components/common/autocomplete.rs index 816bb1b..21c9300 100644 --- a/aep-schedule-website/src/frontend/components/common/autocomplete.rs +++ b/aep-schedule-website/src/frontend/components/common/autocomplete.rs @@ -72,28 +72,44 @@ pub fn AutoComplete<F: FnMut(String) + Copy + Clone + 'static>( view! { <div class="relative search-container ".to_owned() + &class> - <input type="text" class="py-2 px-3 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none text-black" on:input=on_input placeholder=placeholder prop:value=input id=id on:keyup=move |ev| { - if ev.key() == "Enter" && !is_hidden.get() { - let course = input.get().trim().to_uppercase(); - select_choice(course); + <input + type="text" + class="py-2 px-3 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none text-black" + on:input=on_input + placeholder=placeholder + prop:value=input + id=id + on:keyup=move |ev| { + if ev.key() == "Enter" && !is_hidden.get() { + let course = input.get().trim().to_uppercase(); + select_choice(course); + } } - } /> - <button class=button_theme on:pointerdown=move |_| { - let input = input.get().trim().to_uppercase(); - select_choice(input); - }> - <PlusCircle size="2em"/> + <button + class=button_theme + on:pointerdown=move |_| { + let input = input.get().trim().to_uppercase(); + select_choice(input); + } + > + <PlusCircle size="2em" /> </button> <div class="result-box"> - {suggestions.into_iter().enumerate().map(|(i, autocomplete)| view!{ - <div - class=("hidden", move || {!suggestion_range.get().contains(&i)}) - on:pointerdown=move |_| select_choice(autocomplete.value.clone()) - > - {autocomplete.label} - </div> - }).collect_view()} + {suggestions + .into_iter() + .enumerate() + .map(|(i, autocomplete)| { + view! { + <div + class=("hidden", move || { !suggestion_range.get().contains(&i) }) + on:pointerdown=move |_| select_choice(autocomplete.value.clone()) + > + {autocomplete.label} + </div> + } + }) + .collect_view()} </div> </div> } diff --git a/aep-schedule-website/src/frontend/components/common/number_input.rs b/aep-schedule-website/src/frontend/components/common/number_input.rs index c5ded8d..4c2e5a2 100644 --- a/aep-schedule-website/src/frontend/components/common/number_input.rs +++ b/aep-schedule-website/src/frontend/components/common/number_input.rs @@ -36,9 +36,25 @@ where <div class="flex flex-row gap-8 items-center"> <p class="text-white font-sans font-medium tracking-tight">{label}</p> <div class="relative flex items-center max-w-20"> - <button on:pointerdown=minus type="button" class="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-s-lg p-1 h-7 focus:ring-gray-100 focus:ring-2 focus:outline-none"> - <svg class="w-3 h-3 text-gray-900" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 2"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h16"/> + <button + on:pointerdown=minus + type="button" + class="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-s-lg p-1 h-7 focus:ring-gray-100 focus:ring-2 focus:outline-none" + > + <svg + class="w-3 h-3 text-gray-900" + aria-hidden="true" + xmlns="http://www.w3.org/2000/svg" + fill="none" + viewBox="0 0 18 2" + > + <path + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M1 1h16" + /> </svg> </button> <input @@ -49,10 +65,27 @@ where min="0" max=max prop:value=value - required /> - <button on:pointerdown=plus type="button" class="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-e-lg p-1 h-7 focus:ring-gray-100 focus:ring-2 focus:outline-none"> - <svg class="w-3 h-3 text-gray-900" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 18"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 1v16M1 9h16"/> + required + /> + <button + on:pointerdown=plus + type="button" + class="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-e-lg p-1 h-7 focus:ring-gray-100 focus:ring-2 focus:outline-none" + > + <svg + class="w-3 h-3 text-gray-900" + aria-hidden="true" + xmlns="http://www.w3.org/2000/svg" + fill="none" + viewBox="0 0 18 18" + > + <path + stroke="currentColor" + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M9 1v16M1 9h16" + /> </svg> </button> </div> diff --git a/aep-schedule-website/src/frontend/components/common/schedule.rs b/aep-schedule-website/src/frontend/components/common/schedule.rs index 94a2380..8962ea5 100644 --- a/aep-schedule-website/src/frontend/components/common/schedule.rs +++ b/aep-schedule-website/src/frontend/components/common/schedule.rs @@ -21,16 +21,45 @@ pub fn Schedule( view! { <div class="schedule"> - <div class="days" style={format!("grid-template-columns:2em 10px repeat({}, 1fr)", day_week.len())}> + <div + class="days" + style=format!("grid-template-columns:2em 10px repeat({}, 1fr)", day_week.len()) + > <div></div> <div></div> - {day_week.iter().map(|d| view!{<div class="day">{*d}</div>}).collect_view()} + {day_week.iter().map(|d| view! { <div class="day">{*d}</div> }).collect_view()} </div> - <div class="content" style={format!("grid-template-columns:2em 10px repeat({}, 1fr);grid-template-rows: repeat(58, {});", day_week.len(), col_height)}> - {hours.clone().into_iter().enumerate().map(|(i, h)| view!{<div class="time" style={format!("grid-row:{}", 4 * (i + 1))}>{h}</div>}).collect_view()} + <div + class="content" + style=format!( + "grid-template-columns:2em 10px repeat({}, 1fr);grid-template-rows: repeat(58, {});", + day_week.len(), + col_height, + ) + > + {hours + .clone() + .into_iter() + .enumerate() + .map(|(i, h)| { + view! { + <div class="time" style=format!("grid-row:{}", 4 * (i + 1))> + {h} + </div> + } + }) + .collect_view()} <div class="filler-col"></div> - {(3..=(day_week.len()+2)).map(|i| view!{<div class="col" style={format!("grid-column:{i}")}></div>}).collect_view()} - {(1..=hours.len()).map(|i| view!{<div class="row" style={format!("grid-row:{}/ span 2", 4 * i - 1)}></div>}).collect_view()} + {(3..=(day_week.len() + 2)) + .map(|i| view! { <div class="col" style=format!("grid-column:{i}")></div> }) + .collect_view()} + {(1..=hours.len()) + .map(|i| { + view! { + <div class="row" style=format!("grid-row:{}/ span 2", 4 * i - 1)></div> + } + }) + .collect_view()} {children.map(|c| c())} </div> </div> @@ -53,7 +82,7 @@ pub fn ScheduleEvent( len * 4 ); view! { - <div style={style} class="event".to_owned() + &class> + <div style=style class="event".to_owned() + &class> {children()} </div> } diff --git a/aep-schedule-website/src/frontend/components/common/tab.rs b/aep-schedule-website/src/frontend/components/common/tab.rs index 6993eee..014ef07 100644 --- a/aep-schedule-website/src/frontend/components/common/tab.rs +++ b/aep-schedule-website/src/frontend/components/common/tab.rs @@ -3,7 +3,10 @@ use leptos::prelude::*; #[component] pub fn Tab(active_tab: ReadSignal<String>, tab_id: String, children: Children) -> impl IntoView { view! { - <div class="relative card tab shrink w-full overflow-y-auto" class=("hidden", {move || tab_id != active_tab.get()})> + <div + class="relative card tab shrink w-full overflow-y-auto" + class=("hidden", { move || tab_id != active_tab.get() }) + > {children()} </div> } diff --git a/aep-schedule-website/src/frontend/components/icons/download.rs b/aep-schedule-website/src/frontend/components/icons/download.rs index 9bceace..35cbea7 100644 --- a/aep-schedule-website/src/frontend/components/icons/download.rs +++ b/aep-schedule-website/src/frontend/components/icons/download.rs @@ -13,7 +13,7 @@ pub fn Download( match weight { IconWeight::Fill => view! { <path d="M74.34,85.66A8,8,0,0,1,85.66,74.34L120,108.69V24a8,8,0,0,1,16,0v84.69l34.34-34.35a8,8,0,0,1,11.32,11.32l-48,48a8,8,0,0,1-11.32,0ZM240,136v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V136a16,16,0,0,1,16-16H84.4a4,4,0,0,1,2.83,1.17L111,145A24,24,0,0,0,145,145l23.8-23.8A4,4,0,0,1,171.6,120H224A16,16,0,0,1,240,136Zm-40,32a12,12,0,1,0-12,12A12,12,0,0,0,200,168Z"></path> - }.into_any(), + }.into_any(), IconWeight::Duotone => view! { <path d="M232,136v64a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V136a8,8,0,0,1,8-8H224A8,8,0,0,1,232,136Z" diff --git a/aep-schedule-website/src/frontend/components/notifications.rs b/aep-schedule-website/src/frontend/components/notifications.rs index b8adfe6..61dde28 100644 --- a/aep-schedule-website/src/frontend/components/notifications.rs +++ b/aep-schedule-website/src/frontend/components/notifications.rs @@ -44,18 +44,20 @@ pub fn Notifications( view! { <div class=class> <div class="notif-body"> - <div class="close-button" on:pointerdown=move |_| { - set_modal.set(None); - }> + <div + class="close-button" + on:pointerdown=move |_| { + set_modal.set(None); + } + > <X size="2em"></X> </div> <form on:submit=on_submit> - <p>"Entrez votre courriel pour recevoir des notifications quand la section ouvrira"</p> - <input type="text" - pattern=r"[^@\s]+@[^@\s]+\.[^@\s]+" - node_ref=input_element - /> - <input type="submit" value="Envoyer"/> + <p> + "Entrez votre courriel pour recevoir des notifications quand la section ouvrira" + </p> + <input type="text" pattern=r"[^@\s]+@[^@\s]+\.[^@\s]+" node_ref=input_element /> + <input type="submit" value="Envoyer" /> </form> </div> </div> diff --git a/aep-schedule-website/src/frontend/components/options/courses_selector.rs b/aep-schedule-website/src/frontend/components/options/courses_selector.rs index 41f98aa..40e3852 100644 --- a/aep-schedule-website/src/frontend/components/options/courses_selector.rs +++ b/aep-schedule-website/src/frontend/components/options/courses_selector.rs @@ -31,38 +31,43 @@ where // let set_modal = SetModal::from_context(); view! { - <div on:pointerdown=move |_| { + <div + on:pointerdown=move |_| { open.update(|b| *b = !*b); submit(); } class="gap-2 cursor-pointer items-center py-1.5 px-3 rounded-lg flex" - class=("bg-green-500", move || {open.get()}) - class=("bg-red-500", move || {!open.get()}) + class=("bg-green-500", move || { open.get() }) + class=("bg-red-500", move || { !open.get() }) > <span class="text-lg text-bold text-sans">{group.number.to_string()}</span> <div class="flex flex-col justify-between w-full"> - {group.periods.iter().map(|p| { - view!{ - <div class="flex group-text w-full justify-between"> - <span>{p.day.to_string()}</span> - <span class="period-group">{p.hours.to_string()}</span> - <span>{p.week_nb.to_string()}</span> - </div> - } - }).collect_view()} + {group + .periods + .iter() + .map(|p| { + view! { + <div class="flex group-text w-full justify-between"> + <span>{p.day.to_string()}</span> + <span class="period-group">{p.hours.to_string()}</span> + <span>{p.week_nb.to_string()}</span> + </div> + } + }) + .collect_view()} </div> - //{match group.open { - // false => Some(view !{ - // <div on:pointerdown=move |ev| { - // ev.stop_propagation(); - // let sigle_group = SigleGroup::new(course_sigle.clone(), group_type, group.number); - // set_modal.set(Some(sigle_group)); - // }> - // <BellRinging size="1em"/> - // </div> - // }), - // true => None, - //}} + // {match group.open { + // false => Some(view !{ + // <div on:pointerdown=move |ev| { + // ev.stop_propagation(); + // let sigle_group = SigleGroup::new(course_sigle.clone(), group_type, group.number); + // set_modal.set(Some(sigle_group)); + // }> + // <BellRinging size="1em"/> + // </div> + // }), + // true => None, + // }} </div> } } @@ -79,13 +84,22 @@ where F: Fn() + Copy + 'static, { view! { - {groups.into_iter().enumerate().map(|(i, group)| { + {groups + .into_iter() + .enumerate() + .map(|(i, group)| { let open = open[i]; view! { - <GroupsChips open group _course_sigle=course_sigle.clone() _group_type=group_type submit/> + <GroupsChips + open + group + _course_sigle=course_sigle.clone() + _group_type=group_type + submit + /> } - }).collect_view() - } + }) + .collect_view()} } } @@ -99,52 +113,84 @@ where <Tab active_tab tab_id=course.sigle.to_string()> <p>{course.name}</p> <div class="flex justify-around"> - { - match course.course_type { - ReactiveCourseType::TheoOnly { theo_open, theo_groups } => { - let groups = theo_groups; - view!{ - <div class="flex gap-2 flex-col pb-2 max-h-[26rem] overflow-y-auto"> - <h3>"Théorie"</h3> - <GroupsSettings groups open=theo_open course_sigle group_type=GroupType::TheoGroup submit/> - </div> - }.into_any() - }, - ReactiveCourseType::LabOnly { lab_open, lab_groups } => { - let groups = lab_groups; - view!{ - <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> - <h3>"Laboratoire"</h3> - <GroupsSettings groups open=lab_open course_sigle=course_sigle.clone() group_type=GroupType::LabGroup submit/> - </div> - }.into_any() - }, - ReactiveCourseType::Both { theo_open, theo_groups, lab_open, lab_groups } => { - let theo_groups = theo_groups; - let lab_groups = lab_groups; - view!{ - <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> - <h3>"Théorie"</h3> - <GroupsSettings groups=theo_groups open=theo_open course_sigle=course_sigle.clone() group_type=GroupType::TheoGroup submit/> - </div> - <div class="vertical-bar"></div> - <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> - <h3>"Laboratoire"</h3> - <GroupsSettings groups=lab_groups open=lab_open course_sigle=course_sigle.clone() group_type=GroupType::LabGroup submit/> - </div> - }.into_any() - }, - ReactiveCourseType::Linked { both_open, theo_groups, lab_groups } => { - let groups = theo_groups.merge(lab_groups); - view!{ - <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> - <h3>"Théorie et laboratoire lié"</h3> - <GroupsSettings groups open=both_open course_sigle=course_sigle group_type=GroupType::LabGroup submit/> - </div> - }.into_any() - }, + {match course.course_type { + ReactiveCourseType::TheoOnly { theo_open, theo_groups } => { + let groups = theo_groups; + view! { + <div class="flex gap-2 flex-col pb-2 max-h-[26rem] overflow-y-auto"> + <h3>"Théorie"</h3> + <GroupsSettings + groups + open=theo_open + course_sigle + group_type=GroupType::TheoGroup + submit + /> + </div> + } + .into_any() } - } + ReactiveCourseType::LabOnly { lab_open, lab_groups } => { + let groups = lab_groups; + view! { + <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> + <h3>"Laboratoire"</h3> + <GroupsSettings + groups + open=lab_open + course_sigle=course_sigle.clone() + group_type=GroupType::LabGroup + submit + /> + </div> + } + .into_any() + } + ReactiveCourseType::Both { theo_open, theo_groups, lab_open, lab_groups } => { + let theo_groups = theo_groups; + let lab_groups = lab_groups; + view! { + <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> + <h3>"Théorie"</h3> + <GroupsSettings + groups=theo_groups + open=theo_open + course_sigle=course_sigle.clone() + group_type=GroupType::TheoGroup + submit + /> + </div> + <div class="vertical-bar"></div> + <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> + <h3>"Laboratoire"</h3> + <GroupsSettings + groups=lab_groups + open=lab_open + course_sigle=course_sigle.clone() + group_type=GroupType::LabGroup + submit + /> + </div> + } + .into_any() + } + ReactiveCourseType::Linked { both_open, theo_groups, lab_groups } => { + let groups = theo_groups.merge(lab_groups); + view! { + <div class="flex gap-2 flex-col pb-2 overflow-y-auto"> + <h3>"Théorie et laboratoire lié"</h3> + <GroupsSettings + groups + open=both_open + course_sigle=course_sigle + group_type=GroupType::LabGroup + submit + /> + </div> + } + .into_any() + } + }} </div> </Tab> } @@ -161,21 +207,21 @@ where let courses = state.courses; view! { - <Await - future=get_courses() - let:all_courses - > - <SearchCourse set_active_tab all_courses=all_courses.clone()/> + <Await future=get_courses() let:all_courses> + <SearchCourse set_active_tab all_courses=all_courses.clone() /> </Await> <div class="flex w-full flex-wrap gap-1"> - <button class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" class=("opacity-75", move || active_tab.get() != "") id="personal" on:pointerdown={ - move |_| set_active_tab.set("".to_string()) - }> - <CalendarX weight=IconWeight::Regular size="16px"/> + <button + class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" + class=("opacity-75", move || active_tab.get() != "") + id="personal" + on:pointerdown=move |_| set_active_tab.set("".to_string()) + > + <CalendarX weight=IconWeight::Regular size="16px" /> {"Horaire personnel"} </button> <For - each=move || {courses.get()} + each=move || { courses.get() } key=|c| c.sigle.clone() children=move |course| { let sigle = course.sigle.to_string(); @@ -183,22 +229,33 @@ where let sigle = course.sigle.to_string(); let sigle2 = course.sigle.to_string(); let sigle3 = course.sigle.to_string(); - view!{ - <button class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" class=("opacity-75", add_hidden) id=sigle3 on:pointerdown={ - let sigle = sigle.clone(); - move |_| set_active_tab.set(sigle.clone()) - }> - {sigle2} - <button class="close" on:click={ - let sigle = sigle.clone(); - move |_| { - state.courses.update(|courses| { - courses.retain(|c| c.sigle.as_str() != sigle); - }); - submit(); + view! { + <button + class="flex items-center py-1 px-2 rounded-xl bg-amber-500 text-black transition" + class=("opacity-75", add_hidden) + id=sigle3 + on:pointerdown={ + let sigle = sigle.clone(); + move |_| set_active_tab.set(sigle.clone()) } - }> - <X weight=IconWeight::Regular size="16px"/></button> + > + {sigle2} + <button + class="close" + on:click={ + let sigle = sigle.clone(); + move |_| { + state + .courses + .update(|courses| { + courses.retain(|c| c.sigle.as_str() != sigle); + }); + submit(); + } + } + > + <X weight=IconWeight::Regular size="16px" /> + </button> </button> } } @@ -207,12 +264,8 @@ where <Tab active_tab tab_id="".to_string()> <PersonalTimeSelector week=state.week submit></PersonalTimeSelector> </Tab> - <For - each=move || {courses.get()} - key=|c| c.sigle.clone() - let:course - > - <CourseTab course active_tab submit/> + <For each=move || { courses.get() } key=|c| c.sigle.clone() let:course> + <CourseTab course active_tab submit /> </For> } } diff --git a/aep-schedule-website/src/frontend/components/options/form.rs b/aep-schedule-website/src/frontend/components/options/form.rs index 6e6c027..0e1f693 100644 --- a/aep-schedule-website/src/frontend/components/options/form.rs +++ b/aep-schedule-website/src/frontend/components/options/form.rs @@ -31,10 +31,20 @@ pub fn OptionsForms() -> impl IntoView { }; view! { - <CoursesSelector submit/> + <CoursesSelector submit /> <span class="grow"></span> - <NumberInput value=state.max_nb_conflicts max=127 label="Nombre de période de cours en conflits maximum: " submit/> - <SelectOptimizations submit/> - <button on:pointerdown=submit_mobile class="lg:hidden select-none rounded-lg bg-amber-500 py-2 text-xl px-4 w-64 self-center text-center align-middle text-black shadow-md shadow-amber-500/20 transition-all hover:shadow-lg hover:shadow-amber-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none">"Générer les horaires"</button> + <NumberInput + value=state.max_nb_conflicts + max=127 + label="Nombre de période de cours en conflits maximum: " + submit + /> + <SelectOptimizations submit /> + <button + on:pointerdown=submit_mobile + class="lg:hidden select-none rounded-lg bg-amber-500 py-2 text-xl px-4 w-64 self-center text-center align-middle text-black shadow-md shadow-amber-500/20 transition-all hover:shadow-lg hover:shadow-amber-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none" + > + "Générer les horaires" + </button> } } diff --git a/aep-schedule-website/src/frontend/components/options/optimizations.rs b/aep-schedule-website/src/frontend/components/options/optimizations.rs index 918ac1e..bbf62e8 100644 --- a/aep-schedule-website/src/frontend/components/options/optimizations.rs +++ b/aep-schedule-website/src/frontend/components/options/optimizations.rs @@ -31,31 +31,51 @@ where view! { <div class="three-col"> <div class="flex flex-col items-center"> - <House weight=weight_house size="10vh"/> + <House weight=weight_house size="10vh" /> <p class="font-sans font-medium tracking-tight">"Plus de congés"</p> - <input type="range" min="0" max="4" class="lg:w-24 w-16 accent-amber-500" prop:value=state.day_off on:input=move |ev| { - state.day_off.set(event_target_value(&ev).parse::<u8>().unwrap()); - submit(); - }/> + <input + type="range" + min="0" + max="4" + class="lg:w-24 w-16 accent-amber-500" + prop:value=state.day_off + on:input=move |ev| { + state.day_off.set(event_target_value(&ev).parse::<u8>().unwrap()); + submit(); + } + /> </div> <div class="flex flex-col items-center"> <div class="flex"> - <SunHorizon weight=weight_early size="10vh"/> - <Sun weight=weight_morning size="10vh"/> + <SunHorizon weight=weight_early size="10vh" /> + <Sun weight=weight_morning size="10vh" /> </div> <p class="font-sans font-medium tracking-tight">"Cours plus tôt ou plus tard"</p> - <input type="range" min="-4" max="4" class="lg:w-48 w-32 accent-amber-500" prop:value=state.morning on:input=move |ev| { - state.morning.set(event_target_value(&ev).parse::<i8>().unwrap()); - submit(); - }/> + <input + type="range" + min="-4" + max="4" + class="lg:w-48 w-32 accent-amber-500" + prop:value=state.morning + on:input=move |ev| { + state.morning.set(event_target_value(&ev).parse::<i8>().unwrap()); + submit(); + } + /> </div> <div class="flex flex-col items-center"> - <CalendarCheck weight=weight_finish size="10vh"/> + <CalendarCheck weight=weight_finish size="10vh" /> <p class="font-sans font-medium tracking-tight">"Finir plus tôt"</p> - <input type="range" min="0" max="4" class="lg:w-24 w-16 accent-amber-500" prop:value=state.finish_early on:input=move |ev| { - state.finish_early.set(event_target_value(&ev).parse::<u8>().unwrap()); - submit(); - } + <input + type="range" + min="0" + max="4" + class="lg:w-24 w-16 accent-amber-500" + prop:value=state.finish_early + on:input=move |ev| { + state.finish_early.set(event_target_value(&ev).parse::<u8>().unwrap()); + submit(); + } /> </div> </div> diff --git a/aep-schedule-website/src/frontend/components/options/personal.rs b/aep-schedule-website/src/frontend/components/options/personal.rs index fa342b8..3ebbf69 100644 --- a/aep-schedule-website/src/frontend/components/options/personal.rs +++ b/aep-schedule-website/src/frontend/components/options/personal.rs @@ -60,39 +60,47 @@ where }; view! { <Schedule col_height="0.4em"> - {(0..5).into_iter().map(|i| { - (0..26).into_iter().map(|j| { - let j = 2 * j; - let style = format!( - "grid-column:{};grid-row:{} / span {};", - i + 3, - j + 5, - 2 - ); - let class = move || { - let day = week[i].get(); - let hour = day & (1 << j); - if hour != 0 { - "touch-none selected-hour" - } else { - "touch-none" - } - }; - view! { - <div style=style class=class - on:pointerdown=move |e| { - set_initial.set(Some((i, j))); - set_positive.set((week[i].get() & (1 << j)) == 0); - let _ = e.target().unwrap().dyn_ref::<Element>().unwrap().release_pointer_capture(e.pointer_id()); + {(0..5) + .into_iter() + .map(|i| { + (0..26) + .into_iter() + .map(|j| { + let j = 2 * j; + let style = format!( + "grid-column:{};grid-row:{} / span {};", + i + 3, + j + 5, + 2, + ); + let class = move || { + let day = week[i].get(); + let hour = day & (1 << j); + if hour != 0 { "touch-none selected-hour" } else { "touch-none" } + }; + view! { + <div + style=style + class=class + on:pointerdown=move |e| { + set_initial.set(Some((i, j))); + set_positive.set((week[i].get() & (1 << j)) == 0); + let _ = e + .target() + .unwrap() + .dyn_ref::<Element>() + .unwrap() + .release_pointer_capture(e.pointer_id()); + } + on:pointerover=move |_| { + set_destination.set((i, j)); + } + ></div> } - on:pointerover=move |_| { - set_destination.set((i, j)); - }> - </div> - } - }).collect_view() - }).collect_view()} - <div style=selection class=selection_class></div> + }) + .collect_view() + }) + .collect_view()} <div style=selection class=selection_class></div> </Schedule> } } diff --git a/aep-schedule-website/src/frontend/components/options/search.rs b/aep-schedule-website/src/frontend/components/options/search.rs index ab8f109..43d5070 100644 --- a/aep-schedule-website/src/frontend/components/options/search.rs +++ b/aep-schedule-website/src/frontend/components/options/search.rs @@ -26,6 +26,11 @@ pub fn SearchCourse( }; Some(view! { - <AutoComplete suggestion_list=courses placeholder="Cours" submit=on_submit id="course-submitter"/> + <AutoComplete + suggestion_list=courses + placeholder="Cours" + submit=on_submit + id="course-submitter" + /> }) } diff --git a/aep-schedule-website/src/frontend/components/options/todo.rs b/aep-schedule-website/src/frontend/components/options/todo.rs index 5f15b8c..50acbbb 100644 --- a/aep-schedule-website/src/frontend/components/options/todo.rs +++ b/aep-schedule-website/src/frontend/components/options/todo.rs @@ -23,24 +23,40 @@ pub fn Step( view! { <div class="flex"> <div class="flex flex-col items-center mr-4"> - <div> - <div class=bg_color> - <svg class="w-4 text-gray-600" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"> - <line fill="none" stroke-miterlimit="10" x1="12" y1="2" x2="12" y2="22"></line> - <polyline fill="none" stroke-miterlimit="10" points="19,15 12,22 5,15"></polyline> - </svg> + <div> + <div class=bg_color> + <svg + class="w-4 text-gray-600" + stroke="currentColor" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + viewBox="0 0 24 24" + > + <line + fill="none" + stroke-miterlimit="10" + x1="12" + y1="2" + x2="12" + y2="22" + ></line> + <polyline + fill="none" + stroke-miterlimit="10" + points="19,15 12,22 5,15" + ></polyline> + </svg> + </div> </div> - </div> - <div class="w-px h-full bg-gray-300"></div> - </div> - <div class="pt-1 pb-8"> - <p class="mb-2 text-lg font-bold">{n}" - "{title}</p> - <p class="text-gray-700"> - {description} - </p> - {children.map(|c| c())} + <div class="w-px h-full bg-gray-300"></div> + </div> + <div class="pt-1 pb-8"> + <p class="mb-2 text-lg font-bold">{n}" - "{title}</p> + <p class="text-gray-700">{description}</p> + {children.map(|c| c())} + </div> </div> - </div> } } @@ -68,35 +84,79 @@ pub fn Todo() -> impl IntoView { <div class="px-4 py-4 mx-auto"> <div class="grid gap-6 row-gap-10"> <div class="lg:py-6 lg:pr-16"> - <Step n=1 step title="Ajoutez vos cours" description="Utilisez la barre de recherche à gauche pour trouver et sélectionner vos cours. Une fois les cours sélectionnés, ils apparaîtront comme un onglet."/> - <Step n=2 step title="Ouvrez des sections" description="Assurez d'avoir au moins une section d'ouverte pour la théorie et la pratique. En sélectionnant l'onglet du cours et en appuyant sur les sections."> - <div class="warning-box" class=("hidden", move || state.section_error.get().is_empty())> - <WarningCircle size="2em"/> - <span> - {state.section_error} - </span> + <Step + n=1 + step + title="Ajoutez vos cours" + description="Utilisez la barre de recherche à gauche pour trouver et sélectionner vos cours. Une fois les cours sélectionnés, ils apparaîtront comme un onglet." + /> + <Step + n=2 + step + title="Ouvrez des sections" + description="Assurez d'avoir au moins une section d'ouverte pour la théorie et la pratique. En sélectionnant l'onglet du cours et en appuyant sur les sections." + > + <div + class="warning-box" + class=("hidden", move || state.section_error.get().is_empty()) + > + <WarningCircle size="2em" /> + <span>{state.section_error}</span> </div> </Step> - <Step n=3 step title="Forcer des heures libres" description="Sélectionnez une plage de temps à avoir absolument libre en pressant et relâchant sur votre horaire personnel."> - <div class="warning-box" class=("hidden", move || state.personal_error.get().is_empty())> - <WarningCircle size="2em"/> - <span> - {state.personal_error} - </span> + <Step + n=3 + step + title="Forcer des heures libres" + description="Sélectionnez une plage de temps à avoir absolument libre en pressant et relâchant sur votre horaire personnel." + > + <div + class="warning-box" + class=("hidden", move || state.personal_error.get().is_empty()) + > + <WarningCircle size="2em" /> + <span>{state.personal_error}</span> </div> </Step> - <Step n=4 step title="Ajustez les paramètres" description="Bougez les curseurs en bas pour ajuster vos préférences. Vous pouvez choisir d'avoir plus de congés, de commencer en moyenne les cours plus tôt ou plus tard, ou de finir en moyenne plus tôt."/> + <Step + n=4 + step + title="Ajustez les paramètres" + description="Bougez les curseurs en bas pour ajuster vos préférences. Vous pouvez choisir d'avoir plus de congés, de commencer en moyenne les cours plus tôt ou plus tard, ou de finir en moyenne plus tôt." + /> <div class="flex items-center"> <div class="flex flex-col items-center mr-4"> <div> - <div class="flex transition-colors items-center justify-center w-10 h-10 border rounded-full" class=("bg-gray-100", move || step.get() < 5) class=("bg-green-400", move || step.get() == 5) class=("bg-amber-400", move || step.get() == 6) > - <svg class="w-6 text-gray-600" stroke="currentColor" viewBox="0 0 24 24"> - <polyline fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="6,12 10,16 18,8"></polyline> + <div + class="flex transition-colors items-center justify-center w-10 h-10 border rounded-full" + class=("bg-gray-100", move || step.get() < 5) + class=("bg-green-400", move || step.get() == 5) + class=("bg-amber-400", move || step.get() == 6) + > + <svg + class="w-6 text-gray-600" + stroke="currentColor" + viewBox="0 0 24 24" + > + <polyline + fill="none" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + stroke-miterlimit="10" + points="6,12 10,16 18,8" + ></polyline> </svg> </div> </div> </div> - <button on:pointerdown=submit class="select-none rounded-lg bg-amber-500 py-1 text-lg font-sans font-semibold px-2 w-64 self-center text-center align-middle text-black shadow-md shadow-amber-500/20 transition-all hover:shadow-lg hover:shadow-amber-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none" prop:disabled=disab>"Générer les horaires"</button> + <button + on:pointerdown=submit + class="select-none rounded-lg bg-amber-500 py-1 text-lg font-sans font-semibold px-2 w-64 self-center text-center align-middle text-black shadow-md shadow-amber-500/20 transition-all hover:shadow-lg hover:shadow-amber-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none" + prop:disabled=disab + > + "Générer les horaires" + </button> </div> </div> </div> diff --git a/aep-schedule-website/src/frontend/components/schedule.rs b/aep-schedule-website/src/frontend/components/schedule.rs index e7c4cc7..3a5d569 100644 --- a/aep-schedule-website/src/frontend/components/schedule.rs +++ b/aep-schedule-website/src/frontend/components/schedule.rs @@ -90,7 +90,7 @@ fn CoursePeriods(i: usize, course: TakenCourse) -> impl IntoView { .into_iter() .map(|p| { let course = Arc::clone(&course); - view! {<PeriodEvent i period=p course period_type="T"/>} + view! { <PeriodEvent i period=p course period_type="T" /> } }) .collect_view() .into_any(), @@ -99,7 +99,7 @@ fn CoursePeriods(i: usize, course: TakenCourse) -> impl IntoView { .into_iter() .map(|p| { let course = Arc::clone(&course); - view! {<PeriodEvent i period=p course period_type="L"/>} + view! { <PeriodEvent i period=p course period_type="L" /> } }) .collect_view() .into_any(), @@ -111,18 +111,22 @@ fn CoursePeriods(i: usize, course: TakenCourse) -> impl IntoView { theo_group, lab_group, } => view! { - { - theo_group.periods.into_iter().map(|p| { + {theo_group + .periods + .into_iter() + .map(|p| { let course = Arc::clone(&course); - view! {<PeriodEvent i period=p course period_type="T"/>} - }).collect_view() - } - { - lab_group.periods.into_iter().map(|p| { + view! { <PeriodEvent i period=p course period_type="T" /> } + }) + .collect_view()} + {lab_group + .periods + .into_iter() + .map(|p| { let course = Arc::clone(&course); - view! {<PeriodEvent i period=p course period_type="L"/>} - }).collect_view() - } + view! { <PeriodEvent i period=p course period_type="L" /> } + }) + .collect_view()} } .into_any(), } @@ -140,19 +144,31 @@ pub fn ScheduleComponent(schedule: Schedule, calendar: Arc<Calendar>) -> impl In <div class="flex flex-col w-full items-center card p-2"> <a class="hidden" download="cours.ics" href=move || download.get() node_ref=link></a> <table class="cours"> - {courses.into_iter().enumerate().map(|(i, c)| view!{<Course i course={c} />}).collect_view()} + {courses + .into_iter() + .enumerate() + .map(|(i, c)| view! { <Course i course=c /> }) + .collect_view()} </table> - <Schedule last_day=schedule.last_day> - {courses2.into_iter().enumerate().map(|(i, c)| view!{<CoursePeriods i course=c />}).collect_view()} + <Schedule last_day=schedule + .last_day> + {courses2 + .into_iter() + .enumerate() + .map(|(i, c)| view! { <CoursePeriods i course=c /> }) + .collect_view()} </Schedule> - <button class="button-download flex" on:pointerdown=move |_| { - let ics = calendar.generate_ics(&schedule2); - let url = url_escape::encode_fragment(&ics); - set_download("data:text/plain;charset=utf-8,".to_string() + &url); - link.get().unwrap().click(); - }> - <Download weight=IconWeight::Regular size="3vh"/> - <span>"Télécharger le calendrier de cet horaire"</span> + <button + class="button-download flex" + on:pointerdown=move |_| { + let ics = calendar.generate_ics(&schedule2); + let url = url_escape::encode_fragment(&ics); + set_download("data:text/plain;charset=utf-8,".to_string() + &url); + link.get().unwrap().click(); + } + > + <Download weight=IconWeight::Regular size="3vh" /> + <span>"Télécharger le calendrier de cet horaire"</span> </button> </div> } diff --git a/aep-schedule-website/src/frontend/components/schedules.rs b/aep-schedule-website/src/frontend/components/schedules.rs index 17f3d96..2ebe5ca 100644 --- a/aep-schedule-website/src/frontend/components/schedules.rs +++ b/aep-schedule-website/src/frontend/components/schedules.rs @@ -14,40 +14,52 @@ pub fn SchedulesComponent() -> impl IntoView { <Await future=get_calendar() children=move |calendar| { + let calendar = Arc::new(calendar.clone().unwrap()); let bad_generation = state.schedule.get().is_empty(); let generated = state.step.get() == 6; match generated && !bad_generation { true => { - let calendar = Arc::new(calendar.clone().unwrap()); - view !{ + view! { <For each=move || state.schedule.get() - key= |course| course.id - children= move |schedule| { + key=|course| course.id + children=move |schedule| { let calendar = Arc::clone(&calendar); - view !{ - <ScheduleComponent schedule calendar/> - } + view! { <ScheduleComponent schedule calendar /> } } /> - }.into_any() - }, - _ => view ! { - <Todo/> - { - match generated && bad_generation { - true => Some(view !{ - <div class="warning-box"> - <WarningCircle size="4em"/> - <span> - "Aucun horaire n'a pu être généré, augmentez le nombre de conflits ou ouvrez des sections. Probablement que deux groupes sont toujours en conflits." - </span> - </div> - }), + } + .into_any() + } + _ => { + view! { + <Todo /> + <For + each=move || state.schedule.get() + key=|course| course.id + children=move |schedule| { + let calendar = Arc::clone(&calendar); + view! { <ScheduleComponent schedule calendar /> } + } + /> + {match generated && bad_generation { + true => { + Some( + view! { + <div class="warning-box"> + <WarningCircle size="4em" /> + <span> + "Aucun horaire n'a pu être généré, augmentez le nombre de conflits ou ouvrez des sections. Probablement que deux groupes sont toujours en conflits." + </span> + </div> + }, + ) + } false => None, - } + }} } - }.into_any() + .into_any() + } } } /> diff --git a/aep-schedule-website/src/frontend/pages/apropos.rs b/aep-schedule-website/src/frontend/pages/apropos.rs index 4921cbc..36406ba 100644 --- a/aep-schedule-website/src/frontend/pages/apropos.rs +++ b/aep-schedule-website/src/frontend/pages/apropos.rs @@ -5,26 +5,45 @@ pub fn HomePage() -> impl IntoView { view! { <section class="p-1 w-full h-full"> <div class="container flex flex-col justify-center p-4 mx-auto md:p-8"> - <p class="p-2 text-sm font-medium tracking-wider text-center uppercase">"Comment ça marche?"</p> - <h2 class="mb-12 text-4xl font-bold leading-none text-center sm:text-5xl">"Foires aux questions"</h2> + <p class="p-2 text-sm font-medium tracking-wider text-center uppercase"> + "Comment ça marche?" + </p> + <h2 class="mb-12 text-4xl font-bold leading-none text-center sm:text-5xl"> + "Foires aux questions" + </h2> <div class="grid gap-10 md:gap-8 sm:p-3 md:grid-cols-2 lg:px-12"> <div> - <h3 class="font-semibold">"Pourquoi avoir refait l'ancien générateur?"</h3> + <h3 class="font-semibold"> + "Pourquoi avoir refait l'ancien générateur?" + </h3> <p class="mt-1 dark:text-gray-600"> - "L'ancien générateur d'horaire était en mode maintenance depuis au moins 15 ans et changer l'architecture aurait été très difficile, en effet la vénérable base de code contenait littéralement 5 langages de programmation différents!"<br/> "- Marc-Antoine Manningham" + "L'ancien générateur d'horaire était en mode maintenance depuis au moins 15 ans et changer l'architecture aurait été très difficile, en effet la vénérable base de code contenait littéralement 5 langages de programmation différents!" + <br /> "- Marc-Antoine Manningham" </p> </div> <div> - <h3 class="font-semibold">"Qui sont les auteurs de la refonte du générateur d'horaire?"</h3> - <p class="mt-1 dark:text-gray-600">"Marc-Antoine Manningham - Création du frontend et du backend entièrement en Rust. Raphael Salvas, Achille Saint-Hillier, Sunnee Chevalier et Gabriel Billard - Inspiration de leur TP3 de LOG2420 pour l'interface de la refonte du générateur"</p> + <h3 class="font-semibold"> + "Qui sont les auteurs de la refonte du générateur d'horaire?" + </h3> + <p class="mt-1 dark:text-gray-600"> + "Marc-Antoine Manningham - Création du frontend et du backend entièrement en Rust. Raphael Salvas, Achille Saint-Hillier, Sunnee Chevalier et Gabriel Billard - Inspiration de leur TP3 de LOG2420 pour l'interface de la refonte du générateur" + </p> </div> <div> - <h3 class="font-semibold">"Comment le générateur génère aussi vite?"</h3> - <p class="mt-1 dark:text-gray-600">"D'abord, les horaires sont généré directement dans le navigateur de l'utilisateur en WebAssembly plutôt que sur le serveur. Aussi, plutôt que de générer tout les horaires, juste le top des horaires sont générés. Plusieurs techniques pour couper l'espace de combinaisons sont utilisées pour éliminer les branches qui ne respectent pas les contraintes ou qui sont sous-optimales. (branch and bound)"</p> + <h3 class="font-semibold"> + "Comment le générateur génère aussi vite?" + </h3> + <p class="mt-1 dark:text-gray-600"> + "D'abord, les horaires sont généré directement dans le navigateur de l'utilisateur en WebAssembly plutôt que sur le serveur. Aussi, plutôt que de générer tout les horaires, juste le top des horaires sont générés. Plusieurs techniques pour couper l'espace de combinaisons sont utilisées pour éliminer les branches qui ne respectent pas les contraintes ou qui sont sous-optimales. (branch and bound)" + </p> </div> <div> - <h3 class="font-semibold">"Si j'ai des suggestions où aller les mettre?"</h3> - <p class="mt-1 dark:text-gray-600">"Le bouton signaler un bug peut aussi être utilisé pour soumettre une fonctionnalité sur le GitLab. Sinon, les contributions sont aussi les bienvenues si vous êtes prêt à faire un peu de Rust!"</p> + <h3 class="font-semibold"> + "Si j'ai des suggestions où aller les mettre?" + </h3> + <p class="mt-1 dark:text-gray-600"> + "Le bouton signaler un bug peut aussi être utilisé pour soumettre une fonctionnalité sur le GitLab. Sinon, les contributions sont aussi les bienvenues si vous êtes prêt à faire un peu de Rust!" + </p> </div> </div> </div> diff --git a/aep-schedule-website/src/frontend/pages/classroom.rs b/aep-schedule-website/src/frontend/pages/classroom.rs index dbb2186..1e247cd 100644 --- a/aep-schedule-website/src/frontend/pages/classroom.rs +++ b/aep-schedule-website/src/frontend/pages/classroom.rs @@ -55,25 +55,45 @@ pub fn ClassRoomComponent() -> impl IntoView { view! { <section class="flex flex-col w-full justify-between items-center p-4"> <div class="warning-box"> - <WarningCircle size="5em"/> + <WarningCircle size="5em" /> <span> - <span>"Cet horaire est construit à partir de l'horaire général des cours de Polytechnique Montréal. D'autres activités peuvent occuper un local. Pour connaître l'horaire complet d'un local ou le réserver: "</span> - <a href="https://www.polymtl.ca/renseignements-generaux/reserver-une-salle-ou-organiser-un-evenement">"Réserver une salle"</a> + <span> + "Cet horaire est construit à partir de l'horaire général des cours de Polytechnique Montréal. D'autres activités peuvent occuper un local. Pour connaître l'horaire complet d'un local ou le réserver: " + </span> + <a href="https://www.polymtl.ca/renseignements-generaux/reserver-une-salle-ou-organiser-un-evenement"> + "Réserver une salle" + </a> </span> </div> - <Await - future=get_classrooms() - let:classrooms - > - {classrooms.as_ref().map(|classrooms| { - let classrooms = classrooms.into_iter().map(|c| AutoCompleteOption::new(c.to_string(), c.to_string())).collect(); - view!{ - <AutoComplete suggestion_list=classrooms placeholder="Local" class="w-96 shadow-2xl border-b-4 border-amber-500 focus:outline-none focus:ring-0" submit=on_submit id="input-classroom"/> - } - }).ok()} + <Await future=get_classrooms() let:classrooms> + {classrooms + .as_ref() + .map(|classrooms| { + let classrooms = classrooms + .into_iter() + .map(|c| AutoCompleteOption::new(c.to_string(), c.to_string())) + .collect(); + view! { + <AutoComplete + suggestion_list=classrooms + placeholder="Local" + class="w-96 shadow-2xl border-b-4 border-amber-500 focus:outline-none focus:ring-0" + submit=on_submit + id="input-classroom" + /> + } + }) + .ok()} </Await> <Schedule last_day=5 col_height="0.6em"> - {move || periods.get().into_iter().enumerate().map(|(i, p)| view!{<PeriodEvent i period_course=p/>}).collect_view()} + {move || { + periods + .get() + .into_iter() + .enumerate() + .map(|(i, p)| view! { <PeriodEvent i period_course=p /> }) + .collect_view() + }} </Schedule> </section> } diff --git a/aep-schedule-website/src/frontend/pages/generator.rs b/aep-schedule-website/src/frontend/pages/generator.rs index b1504b2..8babed2 100644 --- a/aep-schedule-website/src/frontend/pages/generator.rs +++ b/aep-schedule-website/src/frontend/pages/generator.rs @@ -29,27 +29,28 @@ pub fn GeneratorPage() -> impl IntoView { view! { <aside class="left-panel" class=("hide-left-panel", hide)> - <OptionsForms/> + <OptionsForms /> </aside> - <section class="right-panel" - // on:scroll=move |ev| { - // use web_sys::wasm_bindgen::JsCast; - // let target = ev - // .target() - // .unwrap() - // .dyn_into::<web_sys::Element>() - // .unwrap(); - // let scroll_top = target.scroll_top() as f64; - // let client_height = target.client_height() as f64; - // let scroll_height = target.scroll_height() as f64; - // if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { - // state.regenerate(); - // } + <section class="right-panel"> + // on:scroll=move |ev| { + // use web_sys::wasm_bindgen::JsCast; + // let target = ev + // .target() + // .unwrap() + // .dyn_into::<web_sys::Element>() + // .unwrap(); + // let scroll_top = target.scroll_top() as f64; + // let client_height = target.client_height() as f64; + // let scroll_height = target.scroll_height() as f64; + // if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { + // state.regenerate(); + // } - > - <SchedulesComponent/> + <SchedulesComponent /> </section> - <Notifications modal set_modal/> - <button on:pointerdown=move |_| {hide.set(false)} id="go-back"><CaretDoubleRight weight=IconWeight::Regular size="3vh"/></button> + <Notifications modal set_modal /> + <button on:pointerdown=move |_| { hide.set(false) } id="go-back"> + <CaretDoubleRight weight=IconWeight::Regular size="3vh" /> + </button> } } -- GitLab From bd89ba48b0042d14462ca15f05371232ba1e9551 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Tue, 10 Dec 2024 22:53:47 -0500 Subject: [PATCH 13/15] fix: make the generator work again --- .../src/frontend/components/options/form.rs | 17 +---- .../src/frontend/components/options/search.rs | 5 +- .../src/frontend/components/options/todo.rs | 8 +- .../src/frontend/components/schedules.rs | 73 ++++++++----------- .../src/frontend/pages/generator.rs | 35 ++++----- .../src/frontend/state/action_add_course.rs | 31 ++++++++ .../src/frontend/state/mod.rs | 61 +++++++++------- .../src/frontend/state/reactive_course.rs | 4 +- 8 files changed, 125 insertions(+), 109 deletions(-) create mode 100644 aep-schedule-website/src/frontend/state/action_add_course.rs diff --git a/aep-schedule-website/src/frontend/components/options/form.rs b/aep-schedule-website/src/frontend/components/options/form.rs index 0e1f693..f8e91c1 100644 --- a/aep-schedule-website/src/frontend/components/options/form.rs +++ b/aep-schedule-website/src/frontend/components/options/form.rs @@ -3,31 +3,20 @@ use crate::frontend::{ common::number_input::NumberInput, options::{courses_selector::CoursesSelector, optimizations::SelectOptimizations}, }, - pages::generator::FirstGenerationDone, state::OptionState, }; use leptos::prelude::*; #[component] pub fn OptionsForms() -> impl IntoView { - let first_generation_done: FirstGenerationDone = use_context().unwrap(); - let state = OptionState::from_context(); + let submit = move || { - state.validate(); - if !first_generation_done.0.get() || state.step.get() < 5 { - return; - } - state.generate(); + state.submit(); }; let submit_mobile = move |_| { - state.validate(); - if state.step.get() < 5 { - state.hide.set(true); - return; - } - state.generate(); + state.submit_mobile(); }; view! { diff --git a/aep-schedule-website/src/frontend/components/options/search.rs b/aep-schedule-website/src/frontend/components/options/search.rs index 43d5070..3b66f1a 100644 --- a/aep-schedule-website/src/frontend/components/options/search.rs +++ b/aep-schedule-website/src/frontend/components/options/search.rs @@ -1,6 +1,6 @@ use crate::frontend::{ components::common::autocomplete::{AutoComplete, AutoCompleteOption}, - state::OptionState, + state::action_add_course::ActionAddCourse, }; use aep_schedule_generator::data::course::CourseName; use leptos::prelude::*; @@ -13,13 +13,12 @@ pub fn SearchCourse( let Ok(courses) = all_courses else { return None; }; - let state = OptionState::from_context(); let courses = courses .into_iter() .map(|c| AutoCompleteOption::new(c.sigle.clone(), c.sigle + " - " + &c.name)) .collect(); - let action_courses = state.action_courses; + let action_courses = ActionAddCourse::from_context().0; let on_submit = move |sigle: String| { set_active_tab(sigle.clone()); action_courses.dispatch(sigle); diff --git a/aep-schedule-website/src/frontend/components/options/todo.rs b/aep-schedule-website/src/frontend/components/options/todo.rs index 50acbbb..8104fd7 100644 --- a/aep-schedule-website/src/frontend/components/options/todo.rs +++ b/aep-schedule-website/src/frontend/components/options/todo.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use crate::frontend::components::icons::warning_circle::WarningCircle; -use crate::frontend::{pages::generator::FirstGenerationDone, state::OptionState}; +use crate::frontend::state::OptionState; use leptos::prelude::*; #[component] @@ -62,12 +62,10 @@ pub fn Step( #[component] pub fn Todo() -> impl IntoView { - let first_generation_done: FirstGenerationDone = use_context().unwrap(); - let state = OptionState::from_context(); let submit = move |_| { - first_generation_done.0.set(true); - state.generate(); + state.first_generation_done.set_value(true); + state.submit(); }; let step: RwSignal<u8> = state.step; diff --git a/aep-schedule-website/src/frontend/components/schedules.rs b/aep-schedule-website/src/frontend/components/schedules.rs index 2ebe5ca..4b661e4 100644 --- a/aep-schedule-website/src/frontend/components/schedules.rs +++ b/aep-schedule-website/src/frontend/components/schedules.rs @@ -17,49 +17,40 @@ pub fn SchedulesComponent() -> impl IntoView { let calendar = Arc::new(calendar.clone().unwrap()); let bad_generation = state.schedule.get().is_empty(); let generated = state.step.get() == 6; - match generated && !bad_generation { - true => { - view! { - <For - each=move || state.schedule.get() - key=|course| course.id - children=move |schedule| { - let calendar = Arc::clone(&calendar); - view! { <ScheduleComponent schedule calendar /> } - } - /> + view! { + {move || { + let bad_generation = state.schedule.get().is_empty(); + let generated = state.step.get() == 6; + if !(generated && !bad_generation) { + Some(view! { <Todo /> }) + } else { + None } - .into_any() - } - _ => { - view! { - <Todo /> - <For - each=move || state.schedule.get() - key=|course| course.id - children=move |schedule| { - let calendar = Arc::clone(&calendar); - view! { <ScheduleComponent schedule calendar /> } - } - /> - {match generated && bad_generation { - true => { - Some( - view! { - <div class="warning-box"> - <WarningCircle size="4em" /> - <span> - "Aucun horaire n'a pu être généré, augmentez le nombre de conflits ou ouvrez des sections. Probablement que deux groupes sont toujours en conflits." - </span> - </div> - }, - ) - } - false => None, - }} + }} + {move || { + if generated && bad_generation { + Some( + view! { + <div class="warning-box"> + <WarningCircle size="4em" /> + <span> + "Aucun horaire n'a pu être généré, augmentez le nombre de conflits ou ouvrez des sections. Probablement que deux groupes sont toujours en conflits." + </span> + </div> + }, + ) + } else { + None } - .into_any() - } + }} + <For + each=move || state.schedule.get() + key=|course| course.id + children=move |schedule| { + let calendar = Arc::clone(&calendar); + view! { <ScheduleComponent schedule calendar /> } + } + /> } } /> diff --git a/aep-schedule-website/src/frontend/pages/generator.rs b/aep-schedule-website/src/frontend/pages/generator.rs index 8babed2..c51087b 100644 --- a/aep-schedule-website/src/frontend/pages/generator.rs +++ b/aep-schedule-website/src/frontend/pages/generator.rs @@ -1,9 +1,12 @@ use crate::frontend::components::icons::{caret_double_right::CaretDoubleRight, IconWeight}; use crate::frontend::components::notifications::Notifications; use crate::frontend::components::{options::form::OptionsForms, schedules::SchedulesComponent}; +use crate::frontend::state::action_add_course::ActionAddCourse; use crate::frontend::state::OptionState; use aep_schedule_generator::data::group_sigle::SigleGroup; use leptos::prelude::*; +#[cfg(feature = "hydrate")] +use web_sys::Event; #[derive(Clone, Copy)] pub struct SetModal(WriteSignal<Option<SigleGroup>>); @@ -14,38 +17,32 @@ impl SetModal { } } -#[derive(Clone, Copy)] -pub struct FirstGenerationDone(pub RwSignal<bool>); - #[component] pub fn GeneratorPage() -> impl IntoView { - let first_generation_done = RwSignal::new(false); let (modal, set_modal) = signal(None); let state = OptionState::default(); let hide = state.hide; provide_context(state); provide_context(SetModal(set_modal)); - provide_context(FirstGenerationDone(first_generation_done)); + provide_context(ActionAddCourse::new(state)); + #[cfg(feature = "hydrate")] + let onscroll = move |ev: Event| { + use web_sys::wasm_bindgen::JsCast; + let target = ev.target().unwrap().dyn_into::<web_sys::Element>().unwrap(); + let scroll_top = target.scroll_top() as f64; + let client_height = target.client_height() as f64; + let scroll_height = target.scroll_height() as f64; + if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { + state.regenerate(); + } + }; view! { <aside class="left-panel" class=("hide-left-panel", hide)> <OptionsForms /> </aside> <section class="right-panel"> - // on:scroll=move |ev| { - // use web_sys::wasm_bindgen::JsCast; - // let target = ev - // .target() - // .unwrap() - // .dyn_into::<web_sys::Element>() - // .unwrap(); - // let scroll_top = target.scroll_top() as f64; - // let client_height = target.client_height() as f64; - // let scroll_height = target.scroll_height() as f64; - // if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { - // state.regenerate(); - // } - + on:scroll=onscroll <SchedulesComponent /> </section> <Notifications modal set_modal /> diff --git a/aep-schedule-website/src/frontend/state/action_add_course.rs b/aep-schedule-website/src/frontend/state/action_add_course.rs new file mode 100644 index 0000000..8bd7241 --- /dev/null +++ b/aep-schedule-website/src/frontend/state/action_add_course.rs @@ -0,0 +1,31 @@ +use leptos::prelude::*; + +use crate::backend::routes::get_course; + +use super::OptionState; + +#[derive(Clone)] +pub struct ActionAddCourse(pub Action<String, ()>); + +impl ActionAddCourse { + pub fn from_context() -> Self { + use_context().unwrap() + } + + pub fn new(state: OptionState) -> Self { + let action_courses = Action::new(move |sigle: &String| { + let sigle = sigle.clone(); + async move { + if let Ok(c) = get_course(sigle.clone()).await { + state.courses.update(|courses| { + if !courses.iter().any(|c| c.sigle == sigle) { + courses.push(c.into()); + } + }); + state.submit(); + } + } + }); + Self(action_courses) + } +} diff --git a/aep-schedule-website/src/frontend/state/mod.rs b/aep-schedule-website/src/frontend/state/mod.rs index c51a6e6..fd687f9 100644 --- a/aep-schedule-website/src/frontend/state/mod.rs +++ b/aep-schedule-website/src/frontend/state/mod.rs @@ -7,14 +7,13 @@ use aep_schedule_generator::{ use leptos::prelude::*; use reactive_course::ReactiveCourse; -use crate::backend::routes::get_course; - +pub mod action_add_course; pub mod reactive_course; #[derive(Copy, Clone)] pub struct OptionState { + pub first_generation_done: StoredValue<bool>, pub courses: RwSignal<Vec<ReactiveCourse>>, - pub action_courses: Action<String, ()>, pub week: [RwSignal<u64>; 5], pub max_nb_conflicts: RwSignal<u8>, pub day_off: RwSignal<u8>, @@ -33,10 +32,28 @@ impl OptionState { use_context().unwrap() } - pub fn validate(&self) { + pub fn submit(&self) { + self.validate(); + if !self.first_generation_done.get_value() || self.step.get() < 5 { + return; + } + self.generate(); + } + + pub fn submit_mobile(&self) { + self.validate(); + if self.step.get() < 5 { + self.hide.set(true); + return; + } + self.generate(); + } + + fn validate(&self) { let mut options: SchedulesOptions = self.into(); if options.courses_to_take.is_empty() { self.step.set(1); + self.schedule.set(vec![]); return; } let mut impossible_courses = options.get_impossible_course().into_iter(); @@ -49,6 +66,7 @@ impl OptionState { error.push_str(" sont toutes fermées."); self.section_error.set(error); self.step.set(2); + self.schedule.set(vec![]); return; } self.section_error.set("".to_string()); @@ -63,6 +81,7 @@ impl OptionState { error.push_str(" sont en conflits avec les heures libres sélectionnées."); self.personal_error.set(error); self.step.set(3); + self.schedule.set(vec![]); return; } self.personal_error.set("".to_string()); @@ -73,7 +92,7 @@ impl OptionState { }); } - pub fn generate(&self) { + fn generate(&self) { self.max_size .update_value(|v| v.store(8, Ordering::Relaxed)); self.hide.set(true); @@ -102,22 +121,9 @@ impl Default for OptionState { fn default() -> Self { let courses: RwSignal<Vec<ReactiveCourse>> = RwSignal::new(vec![]); - let action_courses = Action::new(move |sigle: &String| { - let sigle = sigle.clone(); - async move { - if let Ok(c) = get_course(sigle.clone()).await { - courses.update(|courses| { - if !courses.iter().any(|c| c.sigle == sigle) { - courses.push(c.into()); - } - }); - } - } - }); - Self { + first_generation_done: StoredValue::new(false), courses, - action_courses, max_nb_conflicts: RwSignal::new(0), week: std::array::from_fn(|_i| RwSignal::new(0)), day_off: RwSignal::new(3), @@ -135,18 +141,23 @@ impl Default for OptionState { impl From<&OptionState> for SchedulesOptions { fn from(state: &OptionState) -> Self { - let courses_to_take = state.courses.get().into_iter().map(|c| c.into()).collect(); + let courses_to_take = state + .courses + .get_untracked() + .into_iter() + .map(|c| c.into()) + .collect(); let mut max_size = 8; state .max_size .update_value(|v| max_size = v.load(Ordering::Relaxed)); - let max_nb_conflicts = state.max_nb_conflicts.get(); + let max_nb_conflicts = state.max_nb_conflicts.get_untracked(); let evaluation = EvaluationOption { - day_off: state.day_off.get(), - morning: state.morning.get(), - finish_early: state.finish_early.get(), + day_off: state.day_off.get_untracked(), + morning: state.morning.get_untracked(), + finish_early: state.finish_early.get_untracked(), }; - let user_conflicts = Week::new(state.week.map(|s| s.get() << 2)); + let user_conflicts = Week::new(state.week.map(|s| s.get_untracked() << 2)); Self { courses_to_take, max_nb_conflicts, diff --git a/aep-schedule-website/src/frontend/state/reactive_course.rs b/aep-schedule-website/src/frontend/state/reactive_course.rs index 2bda6cd..8f18bb4 100644 --- a/aep-schedule-website/src/frontend/state/reactive_course.rs +++ b/aep-schedule-website/src/frontend/state/reactive_course.rs @@ -61,10 +61,10 @@ impl From<ReactiveCourse> for Course { mut lab_groups, } => { for (i, theo) in theo_open.iter().enumerate() { - theo_groups.get_mut(i.into()).unwrap().open = theo.get(); + theo_groups.get_mut(i.into()).unwrap().open = theo.get_untracked(); } for (i, lab) in lab_open.iter().enumerate() { - lab_groups.get_mut(i.into()).unwrap().open = lab.get(); + lab_groups.get_mut(i.into()).unwrap().open = lab.get_untracked(); } CourseType::Both { theo_groups, -- GitLab From c3c2ee5240b9e6e5ccf40f050def93da953216e6 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Wed, 11 Dec 2024 00:14:39 -0500 Subject: [PATCH 14/15] fix: add the infinite scroll back --- .../src/frontend/pages/generator.rs | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/aep-schedule-website/src/frontend/pages/generator.rs b/aep-schedule-website/src/frontend/pages/generator.rs index c51087b..40094df 100644 --- a/aep-schedule-website/src/frontend/pages/generator.rs +++ b/aep-schedule-website/src/frontend/pages/generator.rs @@ -5,8 +5,6 @@ use crate::frontend::state::action_add_course::ActionAddCourse; use crate::frontend::state::OptionState; use aep_schedule_generator::data::group_sigle::SigleGroup; use leptos::prelude::*; -#[cfg(feature = "hydrate")] -use web_sys::Event; #[derive(Clone, Copy)] pub struct SetModal(WriteSignal<Option<SigleGroup>>); @@ -26,25 +24,24 @@ pub fn GeneratorPage() -> impl IntoView { provide_context(SetModal(set_modal)); provide_context(ActionAddCourse::new(state)); - #[cfg(feature = "hydrate")] - let onscroll = move |ev: Event| { - use web_sys::wasm_bindgen::JsCast; - let target = ev.target().unwrap().dyn_into::<web_sys::Element>().unwrap(); - let scroll_top = target.scroll_top() as f64; - let client_height = target.client_height() as f64; - let scroll_height = target.scroll_height() as f64; - if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { - state.regenerate(); - } - }; view! { <aside class="left-panel" class=("hide-left-panel", hide)> <OptionsForms /> </aside> - <section class="right-panel"> - on:scroll=onscroll + <div class="right-panel" + on:scroll:target=move |ev| { + use web_sys::wasm_bindgen::JsCast; + let target = ev.target().dyn_into::<web_sys::Element>().unwrap(); + let scroll_top = target.scroll_top() as f64; + let client_height = target.client_height() as f64; + let scroll_height = target.scroll_height() as f64; + if (scroll_top + client_height >= scroll_height - 500.0) && state.step.get() == 6 { + state.regenerate(); + } + } + > <SchedulesComponent /> - </section> + </div> <Notifications modal set_modal /> <button on:pointerdown=move |_| { hide.set(false) } id="go-back"> <CaretDoubleRight weight=IconWeight::Regular size="3vh" /> -- GitLab From 506247eb1a95fabe09ce065324f79ebf10b4d36f Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Wed, 11 Dec 2024 00:58:46 -0500 Subject: [PATCH 15/15] fix: remove warning --- aep-schedule-website/src/frontend/state/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aep-schedule-website/src/frontend/state/mod.rs b/aep-schedule-website/src/frontend/state/mod.rs index fd687f9..3e73469 100644 --- a/aep-schedule-website/src/frontend/state/mod.rs +++ b/aep-schedule-website/src/frontend/state/mod.rs @@ -34,7 +34,7 @@ impl OptionState { pub fn submit(&self) { self.validate(); - if !self.first_generation_done.get_value() || self.step.get() < 5 { + if !self.first_generation_done.get_value() || self.step.get_untracked() < 5 { return; } self.generate(); -- GitLab