feat: differentiate area in overview
This commit is contained in:
parent
7d47b38037
commit
43169b585a
@ -1,4 +1,5 @@
|
||||
use actix_web::{web, Responder};
|
||||
use crate::filters;
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use chrono::{NaiveDate, Utc};
|
||||
@ -10,6 +11,7 @@ use crate::models::{Area, Availabillity, Event, Function, Role, User};
|
||||
#[derive(Deserialize)]
|
||||
pub struct CalendarQuery {
|
||||
date: Option<NaiveDate>,
|
||||
area: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
@ -17,6 +19,7 @@ pub struct CalendarQuery {
|
||||
struct CalendarTemplate {
|
||||
user: User,
|
||||
date: NaiveDate,
|
||||
selected_area: Option<i32>,
|
||||
areas: Vec<Area>,
|
||||
events: Vec<Event>,
|
||||
availabillities: Vec<Availabillity>,
|
||||
@ -32,19 +35,40 @@ async fn get(
|
||||
Some(given_date) => given_date,
|
||||
None => Utc::now().date_naive(),
|
||||
};
|
||||
|
||||
let areas = Area::read_all(pool.get_ref()).await.unwrap();
|
||||
|
||||
let events = Event::read_by_date_including_location(pool.get_ref(), date)
|
||||
let selected_area = match query.area {
|
||||
Some(id) => {
|
||||
if !areas.iter().any(|a| a.id == id) {
|
||||
return HttpResponse::BadRequest().finish();
|
||||
}
|
||||
|
||||
Some(id)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
let events = Event::read_by_date_and_area_including_location(
|
||||
pool.get_ref(),
|
||||
date,
|
||||
query.area.unwrap_or(user.area_id),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let availabillities = Availabillity::read_by_date_including_user(pool.get_ref(), date)
|
||||
let availabillities = Availabillity::read_by_date_and_area_including_user(
|
||||
pool.get_ref(),
|
||||
date,
|
||||
query.area.unwrap_or(user.area_id),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let template = CalendarTemplate {
|
||||
user: user.into_inner(),
|
||||
date,
|
||||
selected_area,
|
||||
areas,
|
||||
events,
|
||||
availabillities,
|
||||
|
@ -1,4 +1,3 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use serde::Deserialize;
|
||||
use serde_json::value::Value;
|
||||
|
7
src/filters.rs
Normal file
7
src/filters.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub fn show_area_query(a: &Option<i32>) -> ::askama::Result<String> {
|
||||
if let Some(a) = a {
|
||||
return Ok(format!("&area={}", a));
|
||||
} else {
|
||||
return Ok(String::new());
|
||||
}
|
||||
}
|
@ -19,8 +19,10 @@ mod endpoints;
|
||||
mod models;
|
||||
mod middleware;
|
||||
|
||||
mod filters;
|
||||
mod postgres_session_store;
|
||||
|
||||
|
||||
pub enum Command {
|
||||
Migrate,
|
||||
CreateAdmin,
|
||||
|
@ -33,33 +33,10 @@ impl Availabillity {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn read_by_date(
|
||||
pool: &PgPool,
|
||||
date: NaiveDate,
|
||||
) -> anyhow::Result<Vec<Availabillity>> {
|
||||
let records = query!("SELECT * FROM availabillity WHERE date = $1", date)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let availabillities = records
|
||||
.iter()
|
||||
.map(|a| Availabillity {
|
||||
id: a.id,
|
||||
user_id: a.userid,
|
||||
user: None,
|
||||
date: a.date,
|
||||
start_time: a.starttime,
|
||||
end_time: a.endtime,
|
||||
comment: a.comment.clone(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(availabillities)
|
||||
}
|
||||
|
||||
pub async fn read_by_date_including_user(
|
||||
pub async fn read_by_date_and_area_including_user(
|
||||
pool: &PgPool,
|
||||
date: NaiveDate,
|
||||
area_id: i32
|
||||
) -> anyhow::Result<Vec<Availabillity>> {
|
||||
let records = query!(
|
||||
r##"
|
||||
@ -82,9 +59,11 @@ impl Availabillity {
|
||||
user_.receiveNotifications
|
||||
FROM availabillity
|
||||
JOIN user_ ON availabillity.userId = user_.id
|
||||
WHERE availabillity.date = $1;
|
||||
WHERE availabillity.date = $1
|
||||
AND user_.areaId = $2;
|
||||
"##,
|
||||
date
|
||||
date,
|
||||
area_id
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
@ -34,34 +34,10 @@ impl Event {
|
||||
Ok(result.id)
|
||||
}
|
||||
|
||||
pub async fn read_by_date(pool: &PgPool, date: NaiveDate) -> anyhow::Result<Vec<Event>> {
|
||||
let records = query!("SELECT * FROM event WHERE date = $1;", date)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let events = records
|
||||
.iter()
|
||||
.map(|record| Event {
|
||||
id: record.id,
|
||||
date: record.date,
|
||||
start_time: record.starttime,
|
||||
end_time: record.endtime,
|
||||
name: record.name.to_string(),
|
||||
location_id: record.locationid,
|
||||
location: None,
|
||||
voluntary_wachhabender: record.voluntarywachhabender,
|
||||
amount_of_posten: record.amountofposten,
|
||||
clothing: record.clothing.to_string(),
|
||||
canceled: record.canceled,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
pub async fn read_by_date_including_location(
|
||||
pub async fn read_by_date_and_area_including_location(
|
||||
pool: &PgPool,
|
||||
date: NaiveDate,
|
||||
area_id: i32
|
||||
) -> anyhow::Result<Vec<Event>> {
|
||||
let records = query!(
|
||||
r#"
|
||||
@ -81,9 +57,11 @@ impl Event {
|
||||
location.areaId AS locationAreaId
|
||||
FROM event
|
||||
JOIN location ON event.locationId = location.id
|
||||
WHERE date = $1;
|
||||
WHERE date = $1
|
||||
AND location.areaId = $2;
|
||||
"#,
|
||||
date
|
||||
date,
|
||||
area_id
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
@ -5,14 +5,45 @@
|
||||
<div class="container">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<a hx-boost="true" class="button is-link level-item" href="/?date={{ date.pred() }}">←</a>
|
||||
<a hx-boost="true" class="button is-link level-item"
|
||||
href="/?date={{ date.pred() }}{{ selected_area|show_area_query }}">
|
||||
<span class="icon">
|
||||
<svg class="feather">
|
||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="control level-item is-flex-grow-0">
|
||||
<input id="date-selector" class="input" type="date" value="{{ date }}">
|
||||
{% if user.role == Role::Admin %}
|
||||
<div class="select ml-2">
|
||||
<select hx-get="/?date={{ date }}" hx-target="closest body" hx-push-url="true" name="area">
|
||||
{% for area in areas %}
|
||||
{% if (user.area_id == area.id && selected_area.is_none()) || selected_area.is_some() &&
|
||||
selected_area.unwrap() == area.id %}
|
||||
<option selected value="{{ area.id }}">{{ area.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ area.id }}">{{ area.name }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="level-right">
|
||||
<a hx-boost="true" class="button is-link level-item" href="/?date={{ date.succ() }}">→</a>
|
||||
<a hx-boost="true" class="button is-link level-item"
|
||||
href="/?date={{ date.succ() }}{{ selected_area|show_area_query }}">
|
||||
<span class="icon">
|
||||
<svg class="feather">
|
||||
<use href="/static/feather-sprite.svg#arrow-right" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -25,14 +56,17 @@
|
||||
Events am {{ date.format("%d.%m.%Y") }}
|
||||
</h3>
|
||||
</div>
|
||||
{% if (user.role == Role::Admin || user.role == Role::AreaManager) && (selected_area.is_none() ||
|
||||
selected_area.unwrap() == user.area_id) %}
|
||||
<div class="level-right">
|
||||
<a class="button" href="/events/new?date={{ date }}">Neues Event für diesen Tag</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if events.len() == 0 %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">keine Events geplant</h5>
|
||||
<h5 class="subtitle is-5">keine Events geplant</h5>
|
||||
</div>
|
||||
{% else %}
|
||||
{% for event in events %}
|
||||
@ -67,14 +101,17 @@
|
||||
Verfügbarkeiten am {{ date.format("%d.%m.%Y") }}
|
||||
</h3>
|
||||
</div>
|
||||
{% if (user.role == Role::Admin || user.role == Role::AreaManager) && selected_area.is_some() &&
|
||||
selected_area.unwrap() == user.area_id %}
|
||||
<div class="level-right">
|
||||
<a class="button" href="/availabillity/new?date={{ date }}">Neue Verfügbarkeit für diesen Tag</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if availabillities.len() == 0 %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">keine Verfügbarkeiten eingetragen</h5>
|
||||
<h5 class="subtitle is-5">keine Verfügbarkeiten eingetragen</h5>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="box">
|
||||
|
Loading…
x
Reference in New Issue
Block a user