Updated members list and added groups

This commit is contained in:
Keanu D?lle 2020-08-13 01:05:45 +02:00
parent 7780f2ebfe
commit cfbe4ef28f
20 changed files with 290 additions and 47 deletions

View File

@ -95,4 +95,4 @@ ul ul a {
.sidebar_entry_active{ .sidebar_entry_active{
text-decoration: underline; text-decoration: underline;
} }

View File

@ -0,0 +1,95 @@
{{> header }}
<div class="container-fluid">
<div class="row">
<div class="wrapper" style="width:100%">
{{> sidebar }}
<div id="content" style="width: 100%">
<h1>Member List</h1>
<div class="col-md-6">
<form>
<ul class="nav nav-tabs" id="filterTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="group-tab" data-toggle="tab" href="#group" role="tab" aria-controls="group" aria-selected="true">Group Selection</a>
</li>
<li class="nav-item">
<a class="nav-link" id="searchfields-tab" data-toggle="tab" href="#searchfields" role="tab" aria-controls="searchfields" aria-selected="false">Search fields</a>
</li>
</ul>
<div class="tab-content" id="filterTabContent">
<div class="tab-pane fade show active" id="group" role="tabpanel" aria-labelledby="group-tab">
{{#each group_list}}
<input type="checkbox" id="{{group_id}}">{{name}}</input>
{{/each}}
</div>
<div class="tab-pane fade" id="searchfields" role="tabpanel" aria-labelledby="searchfields-tab">
<div class="form-row">
<div class="col form-group">
<select class="form-control">
<option>first name</option>
<option>last name</option>
<option>date of birth</option>
<option>sex</option>
<option>salutation</option>
<option>place of birth</option>
<option>academic titles</option>
<option>personnel number</option>
<option>ui language</option>
</select>
</div>
<div class="col form-group">
<select class="form-control">
<option>=</option>
<option>!=</option>
<option>LIKE</option>
<option>></option>
<option><</option>
<option>>=</option>
<option><=</option>
</select>
</div>
<div class="col form-group">
<input type="text" class="form-control">
</div>
</div>
</div>
</div>
<button type="submit" class="form-control btn btn-primary" style="width: fit-content;float: right;">Search</button>
</form>
</div>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">personnel number</th>
<th scope="col">first name</th>
<th scope="col">last name</th>
<th scope="col">date of birth</th>
<th scope="col">actions</th>
</tr>
</thead>
<tbody>
{{#each member_list}}
<tr>
<td>{{personnel_number}}</td>
<td>{{firstname}}</td>
<td>{{lastname}}</td>
<td>{{date_of_birth}}</td>
<td><a href="/portal/mm/edit?id={{entity_id}}"><svg width="1.5em" height="1.5em" viewBox="0 0 16 16" class="bi bi-pencil-square" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
<path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
</svg></a>
<a href="/portal/mm/delete?id={{entity_id}}">
<svg width="1.5em" height="1.5em" viewBox="0 0 16 16" class="bi bi-trash" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
</svg>
</a>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
</div>
{{> footer }}

View File

@ -15,11 +15,11 @@
</li> </li>
{{/if}} {{/if}}
{{#if sidebar.member_management.visible}} {{#if sidebar.member_management.visible}}
<li {{#if sidebar.member_management.active}}class="sidebar_entry_active"{{/if}}> <li>
<a href="/portal/mm">Members</a> <a {{#if sidebar.member_management.active}}class="sidebar_entry_active"{{/if}} href="/portal/mm">Members</a>
{{#if sidebar.member_management.active}} {{#if sidebar.member_management.active}}
<ul> <ul>
<li><a href="/portal/mm">List</a></li> <li><a href="/portal/mm">Member List</a></li>
</ul> </ul>
<ul> <ul>
<li><a href="/portal/mm/groups">Groups</a></li> <li><a href="/portal/mm/groups">Groups</a></li>
@ -31,8 +31,8 @@
</li> </li>
{{/if}} {{/if}}
{{#if sidebar.resource_management.visible}} {{#if sidebar.resource_management.visible}}
<li {{#if sidebar.resource_management.active}}class="sidebar_entry_active"{{/if}}> <li>
<a href="/portal/rm">Resources</a> <a {{#if sidebar.resource_management.active}}class="sidebar_entry_active"{{/if}} href="/portal/rm">Resources</a>
{{#if sidebar.resource_management.active}} {{#if sidebar.resource_management.active}}
<ul> <ul>
<li><a href="/portal/rm">List</a></li> <li><a href="/portal/rm">List</a></li>
@ -47,8 +47,8 @@
</li> </li>
{{/if}} {{/if}}
{{#if sidebar.event_management.visible}} {{#if sidebar.event_management.visible}}
<li {{#if sidebar.event_management.active}}class="sidebar_entry_active"{{/if}}> <li>
<a href="/portal/em">Events</a> <a {{#if sidebar.event_management.active}}class="sidebar_entry_active"{{/if}} href="/portal/em">Events</a>
{{#if sidebar.event_management.active}} {{#if sidebar.event_management.active}}
<ul> <ul>
<li><a href="/portal/em">Calendar</a></li> <li><a href="/portal/em">Calendar</a></li>

View File

@ -1,32 +0,0 @@
<!-- Sidebar -->
<nav id="sidebar">
<div class="sidebar-header">
<h3>ERRMS</h3>
<hr>
<div class="user-info">
<p>{{sidebar.member.firstname}} {{sidebar.member.lastname}}</p>
</div>
</div>
<ul class="components sidebar-navigation">
{{#each sidebar.navigation}}
<li>
<a href="{{target}}">{{name}}</a>
{{#if active}}
<ul>
{{#each entries}}
<li>
<a href="{{entry_target}}">{{entry_name}}</a>
</li>
{{/each}}
</ul>
{{/if}}
</li>
{{/each}}
</ul><hr>
<ul class="components sidebar-actions">
<li>
<a href="#1">Add user</a>
</li>
</ul>
</nav>

View File

@ -0,0 +1,26 @@
use crate::database::controller::connector::establish_connection;
use crate::database::model::groups::Group;
use crate::helper::settings::Settings;
use diesel::RunQueryDsl;
use rocket::State;
/// Returns list of all groups
///
/// #Arguments
/// * 'settings' - Settings, as managed State
///
/// #Returns
/// * Vec<Group> - Group items inside Vector
pub fn get_groups(settings: &State<Settings>) -> Vec<Group> {
use crate::schema::groups::dsl::*;
let connection = establish_connection(settings);
let group_vec: Result<Vec<Group>, diesel::result::Error> = groups.load(&connection);
match group_vec {
Ok(group_vec) => group_vec,
Err(e) => {
error!("Error occured while loading groups: {}", e);
vec![]
}
}
}

View File

@ -81,6 +81,9 @@ pub fn get_member_permissions_by_uuid(
/// #Arguments /// #Arguments
/// * 'uuid' - User's uuid, type uuid::Uuid /// * 'uuid' - User's uuid, type uuid::Uuid
/// * 'settings' - Settings, as managed State /// * 'settings' - Settings, as managed State
///
/// #Returns
/// * 'Vec<RawMember>
pub fn get_raw_members_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) -> Vec<RawMember> { pub fn get_raw_members_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) -> Vec<RawMember> {
use crate::schema::members::dsl::*; use crate::schema::members::dsl::*;
use diesel::debug_query; use diesel::debug_query;
@ -101,11 +104,36 @@ pub fn get_raw_members_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) ->
} }
} }
/// Get vector of all members (database::model::members::RawMember)
///
/// #Arguments
/// * 'settings' - Settings, as managed State
///
/// #Returns
/// * 'Vec<RawMember>'
pub fn get_raw_members(settings: &State<Settings>) -> Vec<RawMember> {
use crate::schema::members::dsl::*;
use diesel::debug_query;
let connection = establish_connection(settings);
let member: Result<Vec<RawMember>, diesel::result::Error> = members.load(&connection);
match member {
Ok(member) => member,
Err(e) => {
error!("Error occured while loading data for member: {}", e);
vec![]
}
}
}
/// Get member_management::model::member::Member /// Get member_management::model::member::Member
/// ///
/// #Arguments /// #Arguments
/// * 'uuid' - Users's uuid, type uuid::Uuid /// * 'uuid' - Users's uuid, type uuid::Uuid
/// * 'settings' - Settings, as managed State /// * 'settings' - Settings, as managed State
/// #Returns
/// * 'Vec<Member>'
pub fn get_member_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) -> Vec<Member> { pub fn get_member_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) -> Vec<Member> {
let raw_members: Vec<RawMember> = get_raw_members_by_uuid(uuid, settings); let raw_members: Vec<RawMember> = get_raw_members_by_uuid(uuid, settings);
let mut members: Vec<Member> = vec![]; let mut members: Vec<Member> = vec![];
@ -120,3 +148,25 @@ pub fn get_member_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) -> Vec<M
members members
} }
/// Get all member_management::model::member::Member
///
/// #Arguments
/// * 'settings' - Settings, as managed State
///
/// #Returns
/// * 'Vec<Member'
pub fn get_members(settings: &State<Settings>) -> Vec<Member> {
let raw_members: Vec<RawMember> = get_raw_members(settings);
let mut members: Vec<Member> = vec![];
for raw_member in raw_members {
let mut permissions = get_member_permissions_by_uuid(raw_member.entity_id, settings);
let permissions = permissions.unwrap_or(vec![]);
members.push(Member::from((raw_member, permissions)));
}
members
}

View File

@ -1,3 +1,4 @@
pub mod connector; pub mod connector;
pub mod groups;
pub mod members; pub mod members;
pub mod users; pub mod users;

View File

@ -0,0 +1,8 @@
use uuid::Uuid;
#[derive(Queryable, Clone, Deserialize, Serialize)]
pub struct Group {
pub(crate) group_id: Uuid,
pub(crate) name: String,
pub(crate) description: Option<String>,
}

View File

@ -1,7 +1,7 @@
use chrono::NaiveDate; use chrono::NaiveDate;
use diesel::sql_types::SmallInt; use diesel::sql_types::SmallInt;
#[derive(Debug, Copy, Clone, AsExpression, FromSqlRow, Deserialize)] #[derive(Debug, Copy, Clone, AsExpression, FromSqlRow, Deserialize, Serialize)]
#[sql_type = "SmallInt"] #[sql_type = "SmallInt"]
pub enum Sex { pub enum Sex {
UNKNOWN = 0, UNKNOWN = 0,

View File

@ -1,4 +1,5 @@
pub mod addresses; pub mod addresses;
pub mod entities; pub mod entities;
pub mod groups;
pub mod members; pub mod members;
pub mod users; pub mod users;

View File

@ -53,6 +53,7 @@ fn main() {
modules::welcome::view::welcome_get::welcome_get, modules::welcome::view::welcome_get::welcome_get,
modules::welcome::view::welcome_post::welcome_post, modules::welcome::view::welcome_post::welcome_post,
modules::welcome::view::login_select_get::login_select_get, modules::welcome::view::login_select_get::login_select_get,
modules::member_management::view::member_management_selection_get::member_management_selection_get,
], ],
) )
.mount("/css", StaticFiles::from("resources/css")) .mount("/css", StaticFiles::from("resources/css"))

View File

@ -12,11 +12,7 @@ pub fn get_context(member: Member) -> DashboardModule {
path: "/css/errms.css".to_string(), path: "/css/errms.css".to_string(),
}], }],
}; };
let footer = Footer { let footer = Footer { scripts: vec![] };
scripts: vec![Script {
path: "test123".to_string(),
}],
};
let mut sidebar = Sidebar::new(member); let mut sidebar = Sidebar::new(member);
sidebar.summary.active = true; sidebar.summary.active = true;

View File

@ -1,2 +1,3 @@
pub mod member_check_permission; pub mod member_check_permission;
pub mod member_trait; pub mod member_trait;
pub mod render;

View File

@ -0,0 +1,29 @@
use crate::database::controller::groups::get_groups;
use crate::database::controller::members::get_members;
use crate::helper::settings::Settings;
use crate::helper::sitebuilder::model::general::{Footer, Header, Stylesheet};
use crate::helper::sitebuilder::model::sidebar::Sidebar;
use crate::modules::member_management::model::member::Member;
use crate::modules::member_management::model::member_module::MemberModuleSelection;
use rocket::State;
pub fn get_selection_context(member: Member, settings: &State<Settings>) -> MemberModuleSelection {
let header = Header {
html_language: "de".to_string(),
site_title: "Member List".to_string(),
stylesheets: vec![Stylesheet {
path: "/css/errms.css".to_string(),
}],
};
let footer = Footer { scripts: vec![] };
let mut sidebar = Sidebar::new(member);
sidebar.member_management.active = true;
MemberModuleSelection {
header,
footer,
sidebar,
member_list: get_members(settings),
group_list: get_groups(settings),
}
}

View File

@ -1,7 +1,7 @@
use crate::database::model::members::Sex; use crate::database::model::members::Sex;
use chrono::NaiveDate; use chrono::NaiveDate;
#[derive(Queryable, Clone, Deserialize)] #[derive(Queryable, Clone, Deserialize, Serialize)]
pub struct Member { pub struct Member {
pub(crate) entity_id: uuid::Uuid, pub(crate) entity_id: uuid::Uuid,
pub(crate) users_id: Option<uuid::Uuid>, pub(crate) users_id: Option<uuid::Uuid>,

View File

@ -0,0 +1,15 @@
use crate::database::model::groups::Group;
use crate::database::model::members::RawMember;
use crate::helper::sitebuilder::model::alerts::Alert;
use crate::helper::sitebuilder::model::general::{Footer, Header};
use crate::helper::sitebuilder::model::sidebar::Sidebar;
use crate::modules::member_management::model::member::Member;
#[derive(Serialize)]
pub struct MemberModuleSelection {
pub header: Header,
pub footer: Footer,
pub sidebar: Sidebar,
pub member_list: Vec<Member>,
pub group_list: Vec<Group>,
}

View File

@ -1 +1,2 @@
pub mod member; pub mod member;
pub mod member_module;

View File

@ -0,0 +1,25 @@
use crate::helper::session_cookies::model::SessionCookie;
use crate::helper::settings::Settings;
use crate::helper::sitebuilder::model::general::{Footer, Header};
use crate::modules::member_management::controller::render::get_selection_context;
use crate::modules::member_management::model::member_module::MemberModuleSelection;
use rocket::http::Status;
use rocket::State;
use rocket_contrib::templates::Template;
#[get("/portal/mm")]
pub fn member_management_selection_get(
cookie: SessionCookie,
settings: State<Settings>,
) -> Result<Template, Status> {
let member = match cookie.member {
//Unwraps member from cookie or send user to login if no member specified (user skipped member selection)
Some(member) => member,
None => return Err(Status::Unauthorized),
};
Ok(Template::render(
"module_member_management_selection",
get_selection_context(member, &settings),
))
}

View File

@ -0,0 +1 @@
pub mod member_management_selection_get;

View File

@ -166,6 +166,27 @@ table! {
} }
} }
table! {
use diesel::sql_types::*;
use diesel_geometry::sql_types::*;
groups (group_id) {
group_id -> Uuid,
group_name -> Text,
group_description -> Nullable<Text>,
}
}
table! {
use diesel::sql_types::*;
use diesel_geometry::sql_types::*;
groups_entities (group_id, entity_id) {
group_id -> Uuid,
entity_id -> Uuid,
}
}
joinable!(addresses_entities -> addresses (address_id)); joinable!(addresses_entities -> addresses (address_id));
joinable!(addresses_entities -> entities (entitiy_id)); joinable!(addresses_entities -> entities (entitiy_id));
joinable!(buildings -> entities (entity_id)); joinable!(buildings -> entities (entity_id));
@ -178,6 +199,8 @@ joinable!(members_roles -> roles (role_id));
joinable!(roles_permissions -> permissions (permission_id)); joinable!(roles_permissions -> permissions (permission_id));
joinable!(vehicles -> entities (entity_id)); joinable!(vehicles -> entities (entity_id));
joinable!(vehicles -> vehicle_categories (entity_id)); joinable!(vehicles -> vehicle_categories (entity_id));
joinable!(groups_entities -> entities (entity_id));
joinable!(groups_entities -> groups (group_id));
allow_tables_to_appear_in_same_query!( allow_tables_to_appear_in_same_query!(
addresses, addresses,
@ -194,4 +217,6 @@ allow_tables_to_appear_in_same_query!(
users, users,
vehicle_categories, vehicle_categories,
vehicles, vehicles,
groups,
groups_entities,
); );