From 39a8ef709c31103db37d9a7bf3ff6b2dc1b4ed81 Mon Sep 17 00:00:00 2001
From: marcantoinem <marc-antoine.m@outlook.com>
Date: Mon, 29 Jul 2024 20:59:02 -0400
Subject: [PATCH] feat:Improve schedule rerendering

---
 .../src/algorithm/schedule.rs                 | 14 +++++++++--
 .../src/algorithm/schedules.rs                |  1 -
 .../src/algorithm/taken_course.rs             |  4 ++--
 aep-schedule-generator/src/data/group.rs      |  2 +-
 aep-schedule-generator/src/data/time/day.rs   |  2 +-
 aep-schedule-generator/src/data/time/hours.rs |  2 +-
 .../src/data/time/period.rs                   |  2 +-
 .../src/data/time/week_number.rs              |  2 +-
 .../src/frontend/components/schedule.rs       |  4 +++-
 .../src/frontend/components/schedules.rs      | 24 +++++++++++++------
 10 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/aep-schedule-generator/src/algorithm/schedule.rs b/aep-schedule-generator/src/algorithm/schedule.rs
index 339516f..1584717 100644
--- a/aep-schedule-generator/src/algorithm/schedule.rs
+++ b/aep-schedule-generator/src/algorithm/schedule.rs
@@ -18,7 +18,10 @@ use ical::{
     ical_property,
     property::Property,
 };
-use std::cmp::Ordering;
+use std::{
+    cmp::Ordering,
+    hash::{DefaultHasher, Hash, Hasher},
+};
 use uuid::Uuid;
 
 #[derive(PartialEq, Debug, Clone)]
@@ -121,14 +124,20 @@ impl<'a> ScheduleBuilder<'a> {
         } else {
             7
         };
-        let taken_courses = self
+        let taken_courses: Vec<TakenCourse> = self
             .taken_courses
             .iter()
             .map(|c| c.build(self.courses))
             .collect();
+
+        let mut hasher = DefaultHasher::new();
+        taken_courses.hash(&mut hasher);
+        let id = hasher.finish();
+
         Schedule {
             taken_courses,
             last_day,
+            id,
         }
     }
 }
@@ -137,6 +146,7 @@ impl<'a> ScheduleBuilder<'a> {
 pub struct Schedule {
     pub taken_courses: Vec<TakenCourse>,
     pub last_day: u8,
+    pub id: u64,
 }
 
 impl Schedule {
diff --git a/aep-schedule-generator/src/algorithm/schedules.rs b/aep-schedule-generator/src/algorithm/schedules.rs
index 3dbf244..5b42bf6 100644
--- a/aep-schedule-generator/src/algorithm/schedules.rs
+++ b/aep-schedule-generator/src/algorithm/schedules.rs
@@ -34,7 +34,6 @@ impl<'a> Schedules<'a> {
             .into_sorted_vec()
             .into_iter()
             .map(|r| r.0.build())
-            .rev()
             .collect()
     }
 
diff --git a/aep-schedule-generator/src/algorithm/taken_course.rs b/aep-schedule-generator/src/algorithm/taken_course.rs
index 5a0e3b3..a7968e3 100644
--- a/aep-schedule-generator/src/algorithm/taken_course.rs
+++ b/aep-schedule-generator/src/algorithm/taken_course.rs
@@ -81,7 +81,7 @@ impl TakenCourseBuilder {
     }
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
 pub enum TakenCourseType {
     TheoOnly { theo_group: Group },
     LabOnly { lab_group: Group },
@@ -89,7 +89,7 @@ pub enum TakenCourseType {
     Linked { theo_group: Group, lab_group: Group },
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TakenCourse {
     pub sigle: String,
     pub name: String,
diff --git a/aep-schedule-generator/src/data/group.rs b/aep-schedule-generator/src/data/group.rs
index 6e0129b..3d6dbde 100644
--- a/aep-schedule-generator/src/data/group.rs
+++ b/aep-schedule-generator/src/data/group.rs
@@ -4,7 +4,7 @@ use super::{
 };
 use serde::{Deserialize, Serialize};
 
-#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Hash)]
 pub struct Group {
     pub number: GroupIndex,
     pub open: bool,
diff --git a/aep-schedule-generator/src/data/time/day.rs b/aep-schedule-generator/src/data/time/day.rs
index ad5bc6b..1771247 100644
--- a/aep-schedule-generator/src/data/time/day.rs
+++ b/aep-schedule-generator/src/data/time/day.rs
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
 // There is no course the saturday at Poly, but knowing them, it wouldn't be far
 // stretched to assume that, it could.
 #[repr(u8)]
-#[derive(Deserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Deserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum Day {
     Monday = 0,
     Tuesday = 1,
diff --git a/aep-schedule-generator/src/data/time/hours.rs b/aep-schedule-generator/src/data/time/hours.rs
index 41e2fda..be21f74 100644
--- a/aep-schedule-generator/src/data/time/hours.rs
+++ b/aep-schedule-generator/src/data/time/hours.rs
@@ -6,7 +6,7 @@ use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Deref};
 
 pub const NO_HOUR: Hours = Hours(0);
 
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
+#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
 pub struct Hours(pub u64);
 
 impl Debug for Hours {
diff --git a/aep-schedule-generator/src/data/time/period.rs b/aep-schedule-generator/src/data/time/period.rs
index d0c46d4..10e4465 100644
--- a/aep-schedule-generator/src/data/time/period.rs
+++ b/aep-schedule-generator/src/data/time/period.rs
@@ -2,7 +2,7 @@ use super::{day::Day, hours::Hours, week_number::WeekNumber};
 use compact_str::CompactString;
 use serde::{Deserialize, Serialize};
 
-#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Period {
     pub day: Day,
     pub room: CompactString,
diff --git a/aep-schedule-generator/src/data/time/week_number.rs b/aep-schedule-generator/src/data/time/week_number.rs
index 56f871f..9b519b6 100644
--- a/aep-schedule-generator/src/data/time/week_number.rs
+++ b/aep-schedule-generator/src/data/time/week_number.rs
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
 use std::fmt::Display;
 
 #[repr(u8)]
-#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum WeekNumber {
     B1 = 0,
     B2 = 1,
diff --git a/aep-schedule-website/src/frontend/components/schedule.rs b/aep-schedule-website/src/frontend/components/schedule.rs
index e90f77c..9ac0044 100644
--- a/aep-schedule-website/src/frontend/components/schedule.rs
+++ b/aep-schedule-website/src/frontend/components/schedule.rs
@@ -1,3 +1,5 @@
+use std::rc::Rc;
+
 use crate::frontend::components::common::schedule::{Schedule, ScheduleEvent};
 use crate::frontend::components::icons::download::Download;
 use crate::frontend::components::icons::IconWeight;
@@ -112,7 +114,7 @@ fn CoursePeriods<'a>(i: usize, course: &'a TakenCourse) -> impl IntoView {
 }
 
 #[component]
-pub fn ScheduleComponent(schedule: Schedule, calendar: Calendar) -> impl IntoView {
+pub fn ScheduleComponent(schedule: Schedule, calendar: Rc<Calendar>) -> impl IntoView {
     let schedule2 = schedule.clone();
     let (download, set_download) = create_signal("".to_string());
     let link: NodeRef<A> = create_node_ref();
diff --git a/aep-schedule-website/src/frontend/components/schedules.rs b/aep-schedule-website/src/frontend/components/schedules.rs
index a03e5aa..0b2b70a 100644
--- a/aep-schedule-website/src/frontend/components/schedules.rs
+++ b/aep-schedule-website/src/frontend/components/schedules.rs
@@ -1,3 +1,5 @@
+use std::rc::Rc;
+
 use crate::frontend::components::options::todo::Todo;
 use crate::{backend::routes::get_calendar, frontend::components::schedule::ScheduleComponent};
 use aep_schedule_generator::algorithm::generation::SchedulesOptions;
@@ -17,13 +19,21 @@ pub fn SchedulesComponent(
             future=get_calendar
             children=move |calendar| {
                 match (read_signal.get(), step.get() == 5) {
-                   (Some(result), true) => result.into_iter().rev().map(|schedule| {
-                                        let calendar = calendar.clone().unwrap();
-                                        let schedule = schedule.clone();
-                                        view! {
-                                            <ScheduleComponent schedule calendar/>
-                                        }
-                                    }).collect_view(),
+                    (Some(_), true) => {
+                        let calendar = Rc::new(calendar.clone().unwrap());
+                        view !{
+                            <For
+                                each=move || {read_signal.get().unwrap()}
+                                key= |course| course.id
+                                children= move |schedule| {
+                                    let calendar = Rc::clone(&calendar);
+                                    view !{
+                                        <ScheduleComponent schedule calendar/>
+                                    }
+                                }
+                            />
+                        }
+                   },
                     _ => view ! {
                         <Todo action step section_error personal_error/>
                     }
-- 
GitLab