Compare commits
3 Commits
feeb0facfc
...
cf12fc51d7
Author | SHA1 | Date | |
---|---|---|---|
cf12fc51d7 | |||
6d6b2c57c5 | |||
b36fb6af89 |
@ -1,3 +1,6 @@
|
||||
pub mod admin;
|
||||
pub mod agenda;
|
||||
pub mod home;
|
||||
pub mod layout;
|
||||
pub mod news;
|
||||
pub mod settings;
|
||||
|
@ -1,231 +1 @@
|
||||
use crate::util::model::member::{Member, MembersMigration};
|
||||
use dioxus::prelude::{dioxus_elements::FileEngine, *};
|
||||
use manganis::ImageAsset;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct UploadedFile {
|
||||
name: String,
|
||||
contents: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Steps {
|
||||
Upload,
|
||||
Verify,
|
||||
Done,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Migration() -> Element {
|
||||
let step = use_signal(|| Steps::Upload);
|
||||
let members_migration = use_signal(|| (0, MembersMigration::new()));
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col items-center justify-center py-10",
|
||||
ul {
|
||||
class: "steps pb-10",
|
||||
li { class: "step step-primary", "Uploaden" },
|
||||
li {
|
||||
class: "step",
|
||||
class: if let Steps::Verify | Steps::Done = *step.read() { { "step-primary" } },
|
||||
"Controleren"
|
||||
},
|
||||
li {
|
||||
class: "step",
|
||||
class: if let Steps::Done = *step.read() { { "step-primary" } },
|
||||
"Klaar"
|
||||
},
|
||||
},
|
||||
match *step.read() {
|
||||
Steps::Upload => rsx! { Upload { step: step, members_migration: members_migration } },
|
||||
Steps::Verify => rsx! { Verify { step: step, members_migration: members_migration } },
|
||||
Steps::Done => rsx! { Done {} },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Upload(step: Signal<Steps>, members_migration: Signal<(u16, MembersMigration)>) -> Element {
|
||||
let mut file_uploaded = use_signal(|| None);
|
||||
|
||||
let mut loading = use_signal(|| false);
|
||||
|
||||
let read_files = move |file_engine: Arc<dyn FileEngine>| async move {
|
||||
let files = file_engine.files();
|
||||
for file_name in &files {
|
||||
if let Some(contents) = file_engine.read_file_to_string(file_name).await {
|
||||
file_uploaded.set(Some(UploadedFile {
|
||||
name: file_name.clone(),
|
||||
contents,
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let upload_files = move |evt: FormEvent| async move {
|
||||
if let Some(file_engine) = evt.files() {
|
||||
read_files(file_engine).await;
|
||||
}
|
||||
};
|
||||
|
||||
let sumbit = move |_evt: FormEvent| async move {
|
||||
match &*file_uploaded.read() {
|
||||
Some(file) => {
|
||||
loading.set(true);
|
||||
|
||||
if let Ok(response) = upload_members_list(file.contents.clone()).await {
|
||||
members_migration.set(response);
|
||||
step.set(Steps::Verify);
|
||||
loading.set(false);
|
||||
}
|
||||
loading.set(false);
|
||||
}
|
||||
None => tracing::info!("File doesn't exists"),
|
||||
}
|
||||
};
|
||||
|
||||
rsx! {
|
||||
form {
|
||||
class: "flex flex-col items-center w-full h-full max-w-md mx-auto px-2",
|
||||
onsubmit: sumbit,
|
||||
h2 { class: "text-xl mb-5", "Selecteer de ledenlijst" },
|
||||
input {
|
||||
r#type: "file",
|
||||
class: "file-input file-input-bordered w-full",
|
||||
accept: ".csv",
|
||||
multiple: false,
|
||||
autocomplete: "off",
|
||||
onchange: upload_files,
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary btn-wide mt-5",
|
||||
disabled: file_uploaded.read().is_none() || loading(),
|
||||
if loading() {
|
||||
span { class: "loading loading-spinner" }
|
||||
}
|
||||
"Uploaden"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Verify(step: Signal<Steps>, members_migration: Signal<(u16, MembersMigration)>) -> Element {
|
||||
let mut loading = use_signal(|| false);
|
||||
|
||||
let submit_accept = move |_| async move {
|
||||
loading.set(true);
|
||||
|
||||
if let Ok(_response) = migration_response(true, members_migration.read().0).await {
|
||||
step.set(Steps::Done);
|
||||
loading.set(false);
|
||||
};
|
||||
loading.set(false);
|
||||
};
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col items-center justify-center w-full mx-auto px-2",
|
||||
h2 { class: "text-xl mb-5", "Controleer de verandering" },
|
||||
div {
|
||||
class: "flex flex-wrap gap-5",
|
||||
div {
|
||||
class: "card bg-base-200 p-5",
|
||||
h2 { class: "card-title mb-1", "Toevoegen" }
|
||||
MembersTable { members: members_migration.read().1.inserted.clone() }
|
||||
}
|
||||
div {
|
||||
class: "card bg-base-200 p-5",
|
||||
h2 { class: "card-title mb-1", "Verwijderen" }
|
||||
MembersTable { members: members_migration.read().1.removed.clone() }
|
||||
}
|
||||
div {
|
||||
class: "card bg-base-200 p-5",
|
||||
h2 { class: "card-title mb-1", "Updaten" }
|
||||
MembersTable { members: members_migration.read().1.updated.clone() }
|
||||
}
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary btn-wide mt-5",
|
||||
onclick: submit_accept,
|
||||
disabled: loading(),
|
||||
if loading() {
|
||||
span { class: "loading loading-spinner" }
|
||||
}
|
||||
"Toepassen"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Done() -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col items-center justify-center w-full mx-auto px-2",
|
||||
h2 { class: "text-xl mb-5", "Ledenlijst is geüpdate" },
|
||||
div {
|
||||
class: "w-80 mt-10",
|
||||
img {
|
||||
src: "/gifs/nick.webp",
|
||||
}
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary btn-wide mt-5",
|
||||
"Terug naar Start"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn MembersTable(members: Vec<Member>) -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
class: "h-[30rem] w-96 overflow-auto font-normal",
|
||||
table {
|
||||
class: "table table-pin-rows",
|
||||
thead {
|
||||
tr {
|
||||
th { "Relatiecode" }
|
||||
th { "Naam" }
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
for member in members {
|
||||
tr {
|
||||
th { "{member.id}" }
|
||||
th { "{member.name.full}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
async fn upload_members_list(input: String) -> Result<(u16, MembersMigration), ServerFnError> {
|
||||
match Member::migrate_proposal(input).await {
|
||||
Ok(r) => Ok(r),
|
||||
Err(err) => Err(ServerFnError::new(err.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
async fn migration_response(correct: bool, id: u16) -> Result<(), ServerFnError> {
|
||||
if correct {
|
||||
match Member::migrate(id).await {
|
||||
Err(err) => Err(ServerFnError::new(err.to_string())),
|
||||
Ok(_) => Ok(()),
|
||||
}?;
|
||||
} else {
|
||||
tracing::info!("Migrations denied");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub mod migration;
|
||||
|
230
src/components/admin/members/migration.rs
Normal file
230
src/components/admin/members/migration.rs
Normal file
@ -0,0 +1,230 @@
|
||||
use crate::util::model::member::{Member, MembersMigration};
|
||||
use dioxus::prelude::{dioxus_elements::FileEngine, *};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct UploadedFile {
|
||||
name: String,
|
||||
contents: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Steps {
|
||||
Upload,
|
||||
Verify,
|
||||
Done,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Migration() -> Element {
|
||||
let step = use_signal(|| Steps::Upload);
|
||||
let members_migration = use_signal(|| (0, MembersMigration::new()));
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col items-center justify-center py-10",
|
||||
ul {
|
||||
class: "steps pb-10",
|
||||
li { class: "step step-primary", "Uploaden" },
|
||||
li {
|
||||
class: "step",
|
||||
class: if let Steps::Verify | Steps::Done = *step.read() { { "step-primary" } },
|
||||
"Controleren"
|
||||
},
|
||||
li {
|
||||
class: "step",
|
||||
class: if let Steps::Done = *step.read() { { "step-primary" } },
|
||||
"Klaar"
|
||||
},
|
||||
},
|
||||
match *step.read() {
|
||||
Steps::Upload => rsx! { Upload { step: step, members_migration: members_migration } },
|
||||
Steps::Verify => rsx! { Verify { step: step, members_migration: members_migration } },
|
||||
Steps::Done => rsx! { Done {} },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Upload(step: Signal<Steps>, members_migration: Signal<(u16, MembersMigration)>) -> Element {
|
||||
let mut file_uploaded = use_signal(|| None);
|
||||
|
||||
let mut loading = use_signal(|| false);
|
||||
|
||||
let read_files = move |file_engine: Arc<dyn FileEngine>| async move {
|
||||
let files = file_engine.files();
|
||||
for file_name in &files {
|
||||
if let Some(contents) = file_engine.read_file_to_string(file_name).await {
|
||||
file_uploaded.set(Some(UploadedFile {
|
||||
name: file_name.clone(),
|
||||
contents,
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let upload_files = move |evt: FormEvent| async move {
|
||||
if let Some(file_engine) = evt.files() {
|
||||
read_files(file_engine).await;
|
||||
}
|
||||
};
|
||||
|
||||
let sumbit = move |_evt: FormEvent| async move {
|
||||
match &*file_uploaded.read() {
|
||||
Some(file) => {
|
||||
loading.set(true);
|
||||
|
||||
if let Ok(response) = upload_members_list(file.contents.clone()).await {
|
||||
members_migration.set(response);
|
||||
step.set(Steps::Verify);
|
||||
loading.set(false);
|
||||
}
|
||||
loading.set(false);
|
||||
}
|
||||
None => tracing::info!("File doesn't exists"),
|
||||
}
|
||||
};
|
||||
|
||||
rsx! {
|
||||
form {
|
||||
class: "flex flex-col items-center w-full h-full max-w-md mx-auto px-2",
|
||||
onsubmit: sumbit,
|
||||
h2 { class: "text-xl mb-5", "Selecteer de ledenlijst" },
|
||||
input {
|
||||
r#type: "file",
|
||||
class: "file-input file-input-bordered w-full",
|
||||
accept: ".csv",
|
||||
multiple: false,
|
||||
autocomplete: "off",
|
||||
onchange: upload_files,
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary btn-wide mt-5",
|
||||
disabled: file_uploaded.read().is_none() || loading(),
|
||||
if loading() {
|
||||
span { class: "loading loading-spinner" }
|
||||
}
|
||||
"Uploaden"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Verify(step: Signal<Steps>, members_migration: Signal<(u16, MembersMigration)>) -> Element {
|
||||
let mut loading = use_signal(|| false);
|
||||
|
||||
let submit_accept = move |_| async move {
|
||||
loading.set(true);
|
||||
|
||||
if let Ok(_response) = migration_response(true, members_migration.read().0).await {
|
||||
step.set(Steps::Done);
|
||||
loading.set(false);
|
||||
};
|
||||
loading.set(false);
|
||||
};
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col items-center justify-center w-full mx-auto px-2",
|
||||
h2 { class: "text-xl mb-5", "Controleer de verandering" },
|
||||
div {
|
||||
class: "flex flex-wrap gap-5",
|
||||
div {
|
||||
class: "card bg-base-200 p-5",
|
||||
h2 { class: "card-title mb-1", "Toevoegen" }
|
||||
MembersTable { members: members_migration.read().1.inserted.clone() }
|
||||
}
|
||||
div {
|
||||
class: "card bg-base-200 p-5",
|
||||
h2 { class: "card-title mb-1", "Verwijderen" }
|
||||
MembersTable { members: members_migration.read().1.removed.clone() }
|
||||
}
|
||||
div {
|
||||
class: "card bg-base-200 p-5",
|
||||
h2 { class: "card-title mb-1", "Updaten" }
|
||||
MembersTable { members: members_migration.read().1.updated.clone() }
|
||||
}
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary btn-wide mt-5",
|
||||
onclick: submit_accept,
|
||||
disabled: loading(),
|
||||
if loading() {
|
||||
span { class: "loading loading-spinner" }
|
||||
}
|
||||
"Toepassen"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Done() -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col items-center justify-center w-full mx-auto px-2",
|
||||
h2 { class: "text-xl mb-5", "Ledenlijst is geüpdate" },
|
||||
div {
|
||||
class: "w-80 mt-10",
|
||||
img {
|
||||
src: "/gifs/nick.webp",
|
||||
}
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary btn-wide mt-5",
|
||||
"Terug naar Start"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn MembersTable(members: Vec<Member>) -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
class: "h-[30rem] w-96 overflow-auto font-normal",
|
||||
table {
|
||||
class: "table table-pin-rows",
|
||||
thead {
|
||||
tr {
|
||||
th { "Relatiecode" }
|
||||
th { "Naam" }
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
for member in members {
|
||||
tr {
|
||||
th { "{member.id}" }
|
||||
th { "{member.name.full}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
async fn upload_members_list(input: String) -> Result<(u16, MembersMigration), ServerFnError> {
|
||||
match MembersMigration::migrate_proposal(input).await {
|
||||
Ok(r) => Ok(r),
|
||||
Err(err) => Err(ServerFnError::new(err.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
async fn migration_response(correct: bool, id: u16) -> Result<(), ServerFnError> {
|
||||
if correct {
|
||||
match MembersMigration::migrate(id).await {
|
||||
Err(err) => Err(ServerFnError::new(err.to_string())),
|
||||
Ok(_) => Ok(()),
|
||||
}?;
|
||||
} else {
|
||||
tracing::info!("Migrations denied");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
10
src/components/agenda.rs
Normal file
10
src/components/agenda.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn Agenda() -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
h1 { class: "text-xl font-bold text-primary", "Agenda" }
|
||||
}
|
||||
}
|
||||
}
|
@ -17,13 +17,13 @@ pub fn Navbar() -> Element {
|
||||
"Home"
|
||||
},
|
||||
Link {
|
||||
to: Route::Home {},
|
||||
to: Route::News {},
|
||||
class: "btn btn-ghost flex-col flex-nowrap py-1 gap-1 font-normal h-max",
|
||||
icons::Newspaper {},
|
||||
div { class: "font-normal", "Nieuws" }
|
||||
},
|
||||
Link {
|
||||
to: Route::Home {},
|
||||
to: Route::Agenda {},
|
||||
class: "btn btn-ghost flex-col flex-nowrap py-1 gap-1 font-normal h-max",
|
||||
icons::Calendar {},
|
||||
span { class: "font-normal", "Agenda" }
|
||||
|
@ -21,7 +21,7 @@ pub fn Topbar() -> Element {
|
||||
}
|
||||
Link {
|
||||
class: "btn btn-square btn-ghost",
|
||||
to: Route::Home {},
|
||||
to: Route::Settings {},
|
||||
icons::Cog {}
|
||||
}
|
||||
}
|
||||
|
10
src/components/news.rs
Normal file
10
src/components/news.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn News() -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
h1 { class: "text-xl font-bold text-primary", "Nieuws" }
|
||||
}
|
||||
}
|
||||
}
|
10
src/components/settings.rs
Normal file
10
src/components/settings.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn Settings() -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
h1 { class: "text-xl font-bold text-primary", "Settings" }
|
||||
}
|
||||
}
|
||||
}
|
11
src/main.rs
11
src/main.rs
@ -7,14 +7,23 @@ use dioxus::prelude::*;
|
||||
use tracing::{info, Level};
|
||||
|
||||
// Use routes
|
||||
use components::admin::members::Migration;
|
||||
use components::admin::members::migration::Migration;
|
||||
use components::agenda::Agenda;
|
||||
use components::home::Home;
|
||||
use components::news::News;
|
||||
use components::settings::Settings;
|
||||
|
||||
#[derive(Clone, Routable, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum Route {
|
||||
#[layout(Wrapper)]
|
||||
#[route("/")]
|
||||
Home {},
|
||||
#[route("/agenda")]
|
||||
Agenda {},
|
||||
#[route("/news")]
|
||||
News {},
|
||||
#[route("/settings")]
|
||||
Settings {},
|
||||
#[route("/admin/members/migration")]
|
||||
Migration {},
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#[cfg(feature = "server")]
|
||||
use crate::util::surrealdb::DB;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
mod migration;
|
||||
@ -10,10 +9,10 @@ mod migration;
|
||||
pub struct Member {
|
||||
pub id: String,
|
||||
pub name: Name,
|
||||
// pub hours: BTreeSet<String>,
|
||||
// pub groups: BTreeSet<String>,
|
||||
// pub diploma: Option<String>,
|
||||
// pub registration_token: Option<String>,
|
||||
pub hours: Vec<String>,
|
||||
pub groups: Vec<String>,
|
||||
pub diploma: Option<String>,
|
||||
pub registration_token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
|
||||
|
@ -64,16 +64,16 @@ impl Row {
|
||||
first: self.first_name.clone(),
|
||||
full: self.generate_full_name(),
|
||||
},
|
||||
// hours: self.generate_hours(),
|
||||
// groups: BTreeSet::new(),
|
||||
// diploma: self.diploma.clone(),
|
||||
// registration_token: None,
|
||||
hours: self.generate_hours(),
|
||||
groups: Vec::new(),
|
||||
diploma: self.diploma.clone(),
|
||||
registration_token: None,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the hour data from the raw string
|
||||
fn generate_hours(&self) -> BTreeSet<String> {
|
||||
let mut hours: BTreeSet<String> = BTreeSet::new();
|
||||
fn generate_hours(&self) -> Vec<String> {
|
||||
let mut hours: Vec<String> = Vec::new();
|
||||
|
||||
let group_parts: Vec<&str> = self.hours.split(", ").collect();
|
||||
|
||||
@ -82,7 +82,7 @@ impl Row {
|
||||
|
||||
for part in hour_parts {
|
||||
if &*part != "Groep" {
|
||||
hours.insert(part.to_string());
|
||||
hours.push(part.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,8 +104,9 @@ impl Row {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the raw csv file to rust objects
|
||||
fn csv_to_rows(input: String) -> Result<Vec<Row>, Box<dyn std::error::Error>> {
|
||||
impl MembersMigration {
|
||||
// Convert the raw csv file to rust objects
|
||||
fn csv_to_rows(input: String) -> Result<Vec<Row>, Box<dyn std::error::Error>> {
|
||||
let mut members: Vec<Row> = vec![];
|
||||
|
||||
let mut rdr = csv::Reader::from_reader(input.as_bytes());
|
||||
@ -116,10 +117,10 @@ fn csv_to_rows(input: String) -> Result<Vec<Row>, Box<dyn std::error::Error>> {
|
||||
}
|
||||
|
||||
Ok(members)
|
||||
}
|
||||
}
|
||||
|
||||
// Covert the rows to formatted members
|
||||
fn rows_to_members(rows: Vec<Row>) -> Vec<Member> {
|
||||
// Covert the rows to formatted members
|
||||
fn rows_to_members(rows: Vec<Row>) -> Vec<Member> {
|
||||
let mut members: Vec<Member> = vec![];
|
||||
|
||||
for row in rows {
|
||||
@ -127,13 +128,13 @@ fn rows_to_members(rows: Vec<Row>) -> Vec<Member> {
|
||||
}
|
||||
|
||||
members
|
||||
}
|
||||
}
|
||||
|
||||
// Compare the new members list with the current
|
||||
fn combine_members_lists(
|
||||
// Compare the new members list with the current
|
||||
fn combine_members_lists(
|
||||
new_members_list: Vec<Member>,
|
||||
current_members_list: Vec<Member>,
|
||||
) -> MembersMigration {
|
||||
) -> MembersMigration {
|
||||
tracing::info!(
|
||||
"Current: {}, New: {}",
|
||||
current_members_list.len(),
|
||||
@ -164,10 +165,10 @@ fn combine_members_lists(
|
||||
updated_members.push(Member {
|
||||
id: current_member.id,
|
||||
name: new_member_clone.name,
|
||||
// hours: new_member_clone.hours,
|
||||
// groups: current_member.groups,
|
||||
// diploma: new_member_clone.diploma,
|
||||
// registration_token: current_member.diploma,
|
||||
hours: new_member_clone.hours,
|
||||
groups: current_member.groups,
|
||||
diploma: new_member_clone.diploma,
|
||||
registration_token: current_member.diploma,
|
||||
})
|
||||
} else {
|
||||
// Remove member
|
||||
@ -183,24 +184,23 @@ fn combine_members_lists(
|
||||
}
|
||||
}
|
||||
|
||||
MembersMigration {
|
||||
Self {
|
||||
inserted: inserted_members,
|
||||
updated: updated_members,
|
||||
removed: removed_members,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Member {
|
||||
pub async fn migrate_proposal(
|
||||
csv: String,
|
||||
) -> Result<(u16, MembersMigration), Box<dyn std::error::Error>> {
|
||||
let rows = csv_to_rows(csv)?;
|
||||
let rows = Self::csv_to_rows(csv)?;
|
||||
|
||||
let new_members = rows_to_members(rows);
|
||||
let new_members = Self::rows_to_members(rows);
|
||||
|
||||
let current_members = Member::fetch_all().await?;
|
||||
|
||||
let members_migration = combine_members_lists(new_members, current_members);
|
||||
let members_migration = Self::combine_members_lists(new_members, current_members);
|
||||
|
||||
let count = MEMBERS_STORE.lock().await.insert(members_migration.clone());
|
||||
|
||||
@ -221,8 +221,8 @@ impl Member {
|
||||
// TODO add hours and diploma support
|
||||
query = query
|
||||
+ format!(
|
||||
"UPDATE member:{} SET name.first = \"{}\", name.full = \"{}\";",
|
||||
member.id, member.name.first, member.name.full
|
||||
"UPDATE member:{} SET name.first = \"{}\", name.full = \"{}\", hours = {:?}, groups = {:?};",
|
||||
member.id, member.name.first, member.name.full, member.hours, member.groups
|
||||
)
|
||||
.as_str();
|
||||
}
|
||||
@ -231,8 +231,8 @@ impl Member {
|
||||
// TODO add hours and diploma support
|
||||
query = query
|
||||
+ format!(
|
||||
"CREATE member:{} SET name.first = \"{}\", name.full = \"{}\";",
|
||||
member.id, member.name.first, member.name.full
|
||||
"CREATE member:{} SET name.first = \"{}\", name.full = \"{}\", hours = {:?}, groups = {:?};",
|
||||
member.id, member.name.first, member.name.full, member.hours, member.groups
|
||||
)
|
||||
.as_str();
|
||||
}
|
||||
@ -267,14 +267,14 @@ mod tests {
|
||||
first: "First".to_string(),
|
||||
full: "First Last".to_string(),
|
||||
},
|
||||
// hours: BTreeSet::from([
|
||||
// "Wedstrijd".to_string(),
|
||||
// "Z5".to_string(),
|
||||
// "Zaterdag".to_string(),
|
||||
// ]),
|
||||
// groups: BTreeSet::new(),
|
||||
// diploma: Some("LS1".to_string()),
|
||||
// registration_token: None,
|
||||
hours: Vec::from([
|
||||
"Wedstrijd".to_string(),
|
||||
"Z5".to_string(),
|
||||
"Zaterdag".to_string(),
|
||||
]),
|
||||
groups: vec![],
|
||||
diploma: Some("LS1".to_string()),
|
||||
registration_token: None,
|
||||
},
|
||||
Member {
|
||||
id: "D000002".to_string(),
|
||||
@ -282,10 +282,10 @@ mod tests {
|
||||
first: "First2".to_string(),
|
||||
full: "First2 Last2".to_string(),
|
||||
},
|
||||
// hours: BTreeSet::from(["Z5".to_string(), "Zaterdag".to_string()]),
|
||||
// groups: BTreeSet::new(),
|
||||
// diploma: Some("ZR4".to_string()),
|
||||
// registration_token: None,
|
||||
hours: Vec::from(["Z5".to_string(), "Zaterdag".to_string()]),
|
||||
groups: Vec::new(),
|
||||
diploma: Some("ZR4".to_string()),
|
||||
registration_token: None,
|
||||
},
|
||||
];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user