feat: move export to own view
This commit is contained in:
parent
4c58ff867d
commit
33baf479b5
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@ -0,0 +1,16 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = off
|
||||
|
||||
[*.html]
|
||||
indent_style = space
|
||||
indent_size = 2
|
36
src/endpoints/export/get_availability.rs
Normal file
36
src/endpoints/export/get_availability.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::models::{Area, User, Role};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "export/availabilityxml.html")]
|
||||
struct AvailabilityExportTemplate {
|
||||
user: User,
|
||||
areas: Option<Vec<Area>>
|
||||
}
|
||||
|
||||
#[actix_web::get("/export/availability")]
|
||||
pub async fn get(
|
||||
user: web::ReqData<User>,
|
||||
pool: web::Data<PgPool>
|
||||
) -> impl Responder {
|
||||
if user.role != Role::Admin && user.role != Role::AreaManager {
|
||||
return HttpResponse::Unauthorized().finish();
|
||||
}
|
||||
|
||||
let areas = if user.role == Role::Admin {
|
||||
Some(Area::read_all(pool.get_ref()).await.unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let template = AvailabilityExportTemplate {
|
||||
user: user.into_inner(),
|
||||
areas
|
||||
};
|
||||
|
||||
return template.to_response();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{http::header::{ContentDisposition, ContentType, Header, CONTENT_DISPOSITION}, web, HttpResponse, Responder};
|
||||
use actix_web::{http::header::{ContentDisposition, ContentType, CONTENT_DISPOSITION}, web, HttpResponse, Responder};
|
||||
use chrono::{Months, NaiveDate, NaiveTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
@ -33,7 +33,7 @@ struct ExportAvailabillityXml {
|
||||
assigned: bool,
|
||||
}
|
||||
|
||||
#[actix_web::get("/export-availabillities")]
|
||||
#[actix_web::get("/export/availabilitydata")]
|
||||
pub async fn get(
|
||||
pool: web::Data<PgPool>,
|
||||
user: Identity,
|
2
src/endpoints/export/mod.rs
Normal file
2
src/endpoints/export/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod get_availability;
|
||||
pub mod get_availability_data;
|
@ -2,13 +2,13 @@ use actix_web::web::ServiceConfig;
|
||||
use chrono::NaiveDate;
|
||||
use serde::Deserialize;
|
||||
|
||||
mod area;
|
||||
mod assignment;
|
||||
mod availability;
|
||||
mod events;
|
||||
mod export;
|
||||
mod location;
|
||||
mod user;
|
||||
mod assignment;
|
||||
mod get_export;
|
||||
mod area;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IdPath {
|
||||
@ -54,5 +54,6 @@ pub fn init(cfg: &mut ServiceConfig) {
|
||||
cfg.service(area::get_new::get);
|
||||
cfg.service(area::post_new::post);
|
||||
|
||||
cfg.service(get_export::get);
|
||||
cfg.service(export::get_availability::get);
|
||||
cfg.service(export::get_availability_data::get);
|
||||
}
|
||||
|
42
templates/export/availabilityxml.html
Normal file
42
templates/export/availabilityxml.html
Normal file
@ -0,0 +1,42 @@
|
||||
{% extends "nav.html" %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h3 class="title is-3">
|
||||
Verfügbarkeiten nach XML exportieren
|
||||
</h3>
|
||||
<form action="/export/availabilitydata" target="_blank">
|
||||
<div class="field">
|
||||
<label class="label">Jahr</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" name="year" min="2024" max="9999" value="2024" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Monat</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" name="month" min="1" max="12" value="1" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if user.role == Role::Admin %}
|
||||
<div class="field">
|
||||
<label class="label">Bereich</label>
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="area">
|
||||
{% for area in areas.as_ref().unwrap() %}
|
||||
<option value="{{ area.id }}">{{ area.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<input class="button is-primary" type="submit" value="Exportieren" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
@ -104,7 +104,8 @@
|
||||
</td>
|
||||
<td>
|
||||
{% if availabillity.start_time.is_some() && availabillity.end_time.is_some() %}
|
||||
{{ availabillity.start_time.as_ref().unwrap().format("%R") }} bis {{ availabillity.end_time.as_ref().unwrap().format("%R") }}
|
||||
{{ availabillity.start_time.as_ref().unwrap().format("%R") }} bis {{
|
||||
availabillity.end_time.as_ref().unwrap().format("%R") }}
|
||||
{% else %}
|
||||
ganztägig
|
||||
{% endif %}
|
||||
@ -130,45 +131,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h3 class="title is-3">
|
||||
Verfügbarkeiten nach XML exportieren
|
||||
</h3>
|
||||
<form action="/export-availabillities" target="_blank">
|
||||
<div class="field">
|
||||
<label class="label">Jahr</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" name="year" min="2024" max="9999" value="2024" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Monat</label>
|
||||
<div class="control">
|
||||
<input class="input" type="number" name="month" min="1" max="12" value="1" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if user.role == Role::Admin %}
|
||||
<div class="field">
|
||||
<label class="label">Bereich</label>
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="area">
|
||||
{% for area in areas %}
|
||||
<option value="{{ area.id }}">{{ area.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<input class="button is-primary" type="submit" value="Exportieren" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
document.getElementsByName("delete-availabillity")
|
||||
.forEach(ele => ele.addEventListener("click", (event) => {
|
||||
|
@ -69,8 +69,5 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -15,7 +15,7 @@
|
||||
</div>
|
||||
|
||||
<div class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
<div hx-boost="true" class="navbar-start">
|
||||
<a href="/" class="navbar-item">
|
||||
Kalender
|
||||
</a>
|
||||
@ -23,9 +23,17 @@
|
||||
{% match user.role %}
|
||||
{% when Role::Staff %}
|
||||
{% when Role::AreaManager %}
|
||||
<a class="navbar-item">
|
||||
Planung
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<div class="navbar-item">
|
||||
Export
|
||||
</div>
|
||||
|
||||
<div class="navbar-dropdown">
|
||||
<a href="/export/availability" class="navbar-item">
|
||||
Verfügbarkeiten
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/locations" class="navbar-item">
|
||||
Veranstaltungsorte
|
||||
</a>
|
||||
@ -33,9 +41,17 @@
|
||||
Nutzerverwaltung
|
||||
</a>
|
||||
{% when Role::Admin %}
|
||||
<a class="navbar-item">
|
||||
Planung
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<div class="navbar-item">
|
||||
Export
|
||||
</div>
|
||||
|
||||
<div class="navbar-dropdown">
|
||||
<a href="/export/availability" class="navbar-item">
|
||||
Verfügbarkeiten
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/locations" class="navbar-item">
|
||||
Veranstaltungsorte
|
||||
</a>
|
||||
@ -51,7 +67,12 @@
|
||||
angemeldet als {{ user.name }}
|
||||
<div class="buttons ml-3">
|
||||
<a class="button is-success">
|
||||
Profil
|
||||
<span class="icon">
|
||||
<svg class="feather">
|
||||
<use href="/static/feather-sprite.svg#check-circle" />
|
||||
</svg>
|
||||
</span>
|
||||
<span>Profil</span>
|
||||
</a>
|
||||
<a href="/logout" class="button is-light">
|
||||
Abmelden
|
||||
@ -65,7 +86,8 @@
|
||||
<noscript>
|
||||
<section class="section">
|
||||
<div class="notification is-danger is-light">
|
||||
Dein Browser unterstützt kein JavaScript oder du hast es deaktiviert. Die Funktionalität ist daher auf nur-Lesen beschränkt.
|
||||
Dein Browser unterstützt kein JavaScript oder du hast es deaktiviert. Die Funktionalität ist daher auf
|
||||
nur-Lesen beschränkt.
|
||||
</div>
|
||||
</section>
|
||||
</noscript>
|
||||
|
@ -4,7 +4,8 @@
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">Brass - Anmeldung</h1>
|
||||
<form class="box" action="/login" method="post" hx-boost="true" hx-target-400="#error-message" hx-on:change="document.getElementById('error-message').innerHTML = ''">
|
||||
<form class="box" action="/login" method="post" hx-boost="true" hx-target-400="#error-message"
|
||||
hx-on:change="document.getElementById('error-message').innerHTML = ''">
|
||||
<div class="field">
|
||||
<label class="label" for="email">E-Mail:</label>
|
||||
<div class="control">
|
||||
@ -22,7 +23,14 @@
|
||||
<div id="error-message" class="mb-3 help is-danger"></div>
|
||||
|
||||
<div class="level">
|
||||
<input class="button is-primary level-left" type="submit" value="Anmelden" />
|
||||
<button class="button is-primary level-left">
|
||||
<span class="icon">
|
||||
<svg class="feather">
|
||||
<use href="/static/feather-sprite.svg#log-in" />
|
||||
</svg>
|
||||
</span>
|
||||
<span>Anmelden</span>
|
||||
</button>
|
||||
<a class="button is-info is-light level-right" hx-boost="true" href="/reset-password">Passwort vergessen</a>
|
||||
</div>
|
||||
</form>
|
||||
|
Loading…
x
Reference in New Issue
Block a user