mentorenwahl/frontend/src/routes/settings/users.rs
Dominic Grimm d6dbd18090
Some checks failed
continuous-integration/drone/push Build is failing
Add student vote enable toggle to admin panel
2023-02-04 12:14:11 +01:00

277 lines
13 KiB
Rust

use graphql_client::reqwest::post_graphql;
use yew::prelude::*;
use crate::components;
use crate::graphql;
pub enum Msg {
DoneFetching {
errors: graphql::Errors,
users: Option<Vec<graphql::queries::users::users::UsersUsers>>,
students: Option<Vec<graphql::queries::users_by_role::students::StudentsStudents>>,
teachers: Option<Vec<graphql::queries::users_by_role::teachers::TeachersTeachers>>,
},
SwitchTab(UsersTab),
}
#[derive(Properties, PartialEq, Eq)]
pub struct UsersProps {
pub token: String,
}
#[derive(PartialEq, Clone, Debug)]
pub enum UsersTab {
All,
Students,
Teachers,
}
pub struct Users {
tab: UsersTab,
fetching: bool,
errors: graphql::Errors,
users: Option<Vec<graphql::queries::users::users::UsersUsers>>,
students: Option<Vec<graphql::queries::users_by_role::students::StudentsStudents>>,
teachers: Option<Vec<graphql::queries::users_by_role::teachers::TeachersTeachers>>,
}
impl Component for Users {
type Message = Msg;
type Properties = UsersProps;
fn create(ctx: &Context<Self>) -> Self {
let client = graphql::client(Some(&ctx.props().token)).unwrap();
ctx.link().send_future(async move {
let users_response = post_graphql::<graphql::queries::users::Users, _>(
&client,
graphql::URL.as_str(),
graphql::queries::users::users::Variables,
)
.await
.unwrap();
let students_response = post_graphql::<graphql::queries::users_by_role::Students, _>(
&client,
graphql::URL.as_str(),
graphql::queries::users_by_role::students::Variables,
)
.await
.unwrap();
let teachers_response = post_graphql::<graphql::queries::users_by_role::Teachers, _>(
&client,
graphql::URL.as_str(),
graphql::queries::users_by_role::teachers::Variables,
)
.await
.unwrap();
let x = [
users_response.errors.map_or_else(|| vec![], |e| e),
students_response.errors.map_or_else(|| vec![], |e| e),
teachers_response.errors.map_or_else(|| vec![], |e| e),
]
.concat();
if x.is_empty() {
let mut users = users_response.data.unwrap().users.unwrap();
users.sort_by_key(|x| x.id);
let mut students = students_response.data.unwrap().students.unwrap();
students.sort_by_key(|x| x.id);
let mut teachers = teachers_response.data.unwrap().teachers;
teachers.sort_by_key(|x| x.id);
Msg::DoneFetching {
errors: None,
users: Some(users),
students: Some(students),
teachers: Some(teachers),
}
} else {
Msg::DoneFetching {
errors: graphql::convert(Some(x)),
users: None,
students: None,
teachers: None,
}
}
});
Self {
tab: UsersTab::All,
fetching: true,
errors: None,
users: None,
students: None,
teachers: None,
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::DoneFetching {
errors,
users,
students,
teachers,
} => {
self.fetching = false;
self.errors = errors;
self.users = users;
self.students = students;
self.teachers = teachers;
true
}
Msg::SwitchTab(tab) => {
if self.tab == tab {
false
} else {
self.tab = tab;
true
}
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<fieldset class={classes!("fieldset")}>
<legend>{ "Benutzer" }</legend>
<div class={classes!("tabs")}>
<ul>
<li class={classes!(if self.tab == UsersTab::All { Some("is-active") } else { None })}>
<a onclick={ctx.link().callback(|_| Msg::SwitchTab(UsersTab::All))}>{ "Alle" }</a>
</li>
<li class={classes!(if self.tab == UsersTab::Students { Some("is-active") } else { None })}>
<a onclick={ctx.link().callback(|_| Msg::SwitchTab(UsersTab::Students))}>{ "Schüler" }</a>
</li>
<li class={classes!(if self.tab == UsersTab::Teachers { Some("is-active") } else { None })}>
<a onclick={ctx.link().callback(|_| Msg::SwitchTab(UsersTab::Teachers))}>{ "Lehrer" }</a>
</li>
</ul>
</div>
if self.fetching {
<components::fetching::Fetching />
} else {
<div>
{
match self.tab {
UsersTab::All => html! {
<table class={classes!("table")}>
<thead>
<tr>
<th><abbr title="ID des Benutzers in der Datenbank / API">{ "ID" }</abbr></th>
<th>{ "Nachname" }</th>
<th>{ "Vorname" }</th>
<th>{ "Benutzername" }</th>
<th>{ "Rolle" }</th>
<th><abbr title="ID des externen Benutzerobjekts">{ "Rollen-ID" }</abbr></th>
<th>{ "Admin" }</th>
</tr>
</thead>
<tbody>
{
for self.users.as_ref().unwrap().iter().map(|u| html! {
<tr>
<td><code>{ &u.id }</code></td>
<td>{ &u.last_name }</td>
<td>{ &u.first_name }</td>
<td><code>{ &u.username }</code></td>
<td>
<code>
{
match &u.role {
graphql::queries::users::users::UserRole::Student => "S",
graphql::queries::users::users::UserRole::Teacher => "T",
graphql::queries::users::users::UserRole::Other(_) => "N/A",
}
}
</code>
</td>
// <td><code>{ if let Some(id) = u.external_id { id } else { "N/A" } }</code></td>
<td>
if let Some(id) = u.external_id {
<code>{ id }</code>
} else {
<i>{ "N/A" }</i>
}
</td>
<td><code>{ if u.admin { 1 } else { 0 } }</code></td>
</tr>
})
}
</tbody>
</table>
},
UsersTab::Students => html! {
<table class={classes!("table")}>
<thead>
<tr>
<th><abbr title="ID des Schülers in der Datenbank / API">{ "ID" }</abbr></th>
<th>{ "Nachname" }</th>
<th>{ "Vorname" }</th>
<th>{ "Benutzername" }</th>
<th>{ "Benutzer-ID" }</th>
<th>{ "Admin" }</th>
<th>{ "Gewählt" }</th>
</tr>
</thead>
<tbody>
{
for self.students.as_ref().unwrap().iter().map(|s| html! {
<tr>
<td><code>{ &s.id }</code></td>
<td>{ &s.user.last_name }</td>
<td>{ &s.user.first_name }</td>
<td><code>{ &s.user.username }</code></td>
<td><code>{ &s.user.id }</code></td>
<td><code>{ if s.user.admin { 1 } else { 0 } }</code></td>
<td><code>{ if s.vote.is_some() { 1 } else { 0 } }</code></td>
</tr>
})
}
</tbody>
</table>
},
UsersTab::Teachers => html! {
<table class={classes!("table")}>
<thead>
<tr>
<th><abbr title="ID des Lehrers in der Datenbank / API">{ "ID" }</abbr></th>
<th>{ "Nachname" }</th>
<th>{ "Vorname" }</th>
<th>{ "Benutzername" }</th>
<th>{ "Benutzer-ID" }</th>
<th>{ "Admin" }</th>
</tr>
</thead>
<tbody>
{
for self.teachers.as_ref().unwrap().iter().map(|t| html! {
<tr>
<td><code>{ &t.id }</code></td>
<td>{ &t.user.last_name }</td>
<td>{ &t.user.first_name }</td>
<td><code>{ &t.user.username }</code></td>
<td><code>{ &t.user.id }</code></td>
<td><code>{ if t.user.admin { 1 } else { 0 } }</code></td>
</tr>
})
}
</tbody>
</table>
},
}
}
</div>
<components::graphql_errors::GraphQLErrors errors={self.errors.to_owned()} />
}
</fieldset>
}
}
}