refactor: foreign availabilities
This commit is contained in:
parent
d88fe2cd3a
commit
c2bc0218f4
@ -3,11 +3,44 @@ source: web/src/endpoints/availability/put_cross_areal.rs
|
||||
expression: disable_body
|
||||
snapshot_kind: text
|
||||
---
|
||||
<button class="button is-link is-light" hx-swap="outerHTML"
|
||||
hx-put="/availability/1/makeCrossAreal"
|
||||
title="Bereichsübergreifend verfügbar machen">
|
||||
<svg class="icon">
|
||||
<use
|
||||
href="/static/feather-sprite.svg#globe" />
|
||||
</svg>
|
||||
</button>
|
||||
<tr>
|
||||
<td>Max Mustermann</td>
|
||||
<td>
|
||||
<div class="tags"><span class="tag is-primary is-light">Posten</span></div>
|
||||
</td>
|
||||
<td>
|
||||
10:00 Uhr bis
|
||||
01.02.2025 10:00 Uhr
|
||||
</td>
|
||||
<td></td>
|
||||
<td>nein</td>
|
||||
<td>
|
||||
|
||||
<div class="buttons is-right">
|
||||
<a class="button is-primary is-light" href="/availability/edit/1"
|
||||
title="Verfügbarkeit bearbeiten">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#edit" />
|
||||
</svg>
|
||||
</a>
|
||||
<button class="button is-danger is-light" hx-delete="/availability/delete/1"
|
||||
hx-target="closest tr" hx-swap="delete" hx-trigger="confirmed"
|
||||
title="Verfügbarkeit löschen">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#x-circle" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button class="button is-link is-light" hx-swap="outerHTML" hx-target="closest tr"
|
||||
hx-put="/availability/1/makeCrossAreal"
|
||||
title="Bereichsübergreifend verfügbar machen">
|
||||
<svg class="icon">
|
||||
<use
|
||||
href="/static/feather-sprite.svg#globe" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -3,11 +3,44 @@ source: web/src/endpoints/availability/put_cross_areal.rs
|
||||
expression: enable_body
|
||||
snapshot_kind: text
|
||||
---
|
||||
<button class="button is-link is-light" hx-swap="outerHTML"
|
||||
hx-put="/availability/1/makeNonCrossAreal"
|
||||
title="nur im Hauptbereich verfügbar machen">
|
||||
<svg class="icon">
|
||||
<use
|
||||
href="/static/feather-sprite.svg#home" />
|
||||
</svg>
|
||||
</button>
|
||||
<tr>
|
||||
<td>Max Mustermann</td>
|
||||
<td>
|
||||
<div class="tags"><span class="tag is-primary is-light">Posten</span></div>
|
||||
</td>
|
||||
<td>
|
||||
10:00 Uhr bis
|
||||
01.02.2025 10:00 Uhr
|
||||
</td>
|
||||
<td></td>
|
||||
<td>ja</td>
|
||||
<td>
|
||||
|
||||
<div class="buttons is-right">
|
||||
<a class="button is-primary is-light" href="/availability/edit/1"
|
||||
title="Verfügbarkeit bearbeiten">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#edit" />
|
||||
</svg>
|
||||
</a>
|
||||
<button class="button is-danger is-light" hx-delete="/availability/delete/1"
|
||||
hx-target="closest tr" hx-swap="delete" hx-trigger="confirmed"
|
||||
title="Verfügbarkeit löschen">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#x-circle" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button class="button is-link is-light" hx-swap="outerHTML" hx-target="closest tr"
|
||||
hx-put="/availability/1/makeNonCrossAreal"
|
||||
title="nur im Hauptbereich verfügbar machen">
|
||||
<svg class="icon">
|
||||
<use
|
||||
href="/static/feather-sprite.svg#home" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,18 +1,26 @@
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama::{filters::urlencode, Template};
|
||||
use serde_json::json;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{
|
||||
endpoints::IdPath,
|
||||
utils::{ApplicationError, TemplateResponse},
|
||||
filters,
|
||||
utils::{
|
||||
ApplicationError,
|
||||
DateTimeFormat::{DayMonthYearHourMinute, HourMinute},
|
||||
TemplateResponse,
|
||||
},
|
||||
};
|
||||
|
||||
use brass_db::models::{Assignment, Availability, Role, User};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "calendar_cross_areal_button.html")]
|
||||
struct CalendarPartialCrossArealButtonTemplate {
|
||||
#[template(path = "calendar_tr_availability.html")]
|
||||
struct CalendarAvailabilityTableRowTemplate {
|
||||
user: User,
|
||||
availability: Availability,
|
||||
u: User,
|
||||
}
|
||||
|
||||
#[actix_web::put("/availability/{id}/makeNonCrossAreal")]
|
||||
@ -60,7 +68,7 @@ async fn handle_cross_areal(
|
||||
let trigger = json!({
|
||||
"showToast": {
|
||||
"type": "danger",
|
||||
"message": "Verfügbarkeit bereits verplant!"
|
||||
"message": urlencode("Verfügbarkeit bereits verplant!").unwrap().to_string()
|
||||
}
|
||||
})
|
||||
.to_string();
|
||||
@ -75,7 +83,13 @@ async fn handle_cross_areal(
|
||||
availability.cross_areal = cross_areal;
|
||||
}
|
||||
|
||||
let template = CalendarPartialCrossArealButtonTemplate { availability };
|
||||
let u = availability.user.as_ref().unwrap().clone();
|
||||
|
||||
let template = CalendarAvailabilityTableRowTemplate {
|
||||
availability,
|
||||
user: user.into_inner(),
|
||||
u,
|
||||
};
|
||||
Ok(template.to_response()?)
|
||||
}
|
||||
|
||||
@ -102,7 +116,9 @@ mod tests {
|
||||
RequestConfig::new("/availability/1/makeCrossAreal").with_role(Role::AreaManager);
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
|
||||
let mut changeset: UserChangeset = Faker.fake();
|
||||
changeset.name = "Max Mustermann".to_string();
|
||||
User::create(&context.db_pool, &changeset).await.unwrap();
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
|
@ -60,7 +60,7 @@ setThemeSwitcherIconTo(isCurrentlyLight ? "moon" : "sun");
|
||||
htmx.on("showToast", (e) => {
|
||||
const toast = document.getElementById("toast");
|
||||
const toastProgress = document.getElementById("toast-progress");
|
||||
document.getElementById("toast-message").innerText = e.detail.message;
|
||||
document.getElementById("toast-message").innerText = decodeURI(e.detail.message);
|
||||
|
||||
toast.classList.add(`is-${e.detail.type}`);
|
||||
toastProgress.classList.add(`has-background-${e.detail.type}-90`)
|
||||
|
@ -13,6 +13,8 @@
|
||||
<input type="hidden" name="enddate" value="{{ enddate.as_ref().unwrap_or(date) }}" id="enddate">
|
||||
|
||||
{% if other_users.len() != 0 %}
|
||||
<input type="hidden" name="user" id="otheruser" value="{{ other_user.unwrap_or_default() }}">
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Nutzer</label>
|
||||
@ -21,12 +23,13 @@
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="user" required {{ id.is_some()|ref|cond_show("disabled") }}>
|
||||
<select required {{ id.is_some()|ref|cond_show("disabled") }}>
|
||||
{% for u in other_users %}
|
||||
<option value="{{ u.id }}" hx-get="/availability/new-other?date={{ date }}&user={{ u.id }}"
|
||||
<option hx-get="/availability/new-other?date={{ date }}&user={{ u.id }}"
|
||||
{{ (other_user.is_some() && *other_user.as_ref().unwrap()==u.id)|cond_show("selected") }}>
|
||||
{{ u.name }}
|
||||
{% if user.role == Role::Admin && u.area.is_some() %} - ({{ u.area.as_ref().unwrap().name }}){% endif %}
|
||||
{% if user.role == Role::Admin && u.area.is_some() %} - ({{ u.area.as_ref().unwrap().name }}){%
|
||||
endif %}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
@ -305,48 +305,16 @@
|
||||
<th>Funktion</th>
|
||||
<th>Zeitraum</th>
|
||||
<th>Kommentar</th>
|
||||
{% if user.role == Role::AreaManager || user.role == Role::Admin %}
|
||||
<th>bereichsübergreifend</th>
|
||||
{% endif %}
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for availability in availabilities %}
|
||||
{% let u = availability.user.as_ref().unwrap() %}
|
||||
<tr>
|
||||
<td>{{ u.name }}</td>
|
||||
<td>
|
||||
{{ u.function|show_tree|safe }}
|
||||
</td>
|
||||
<td>
|
||||
{{ availability.start|fmt_datetime(HourMinute) }} Uhr bis
|
||||
{{ availability.end|fmt_datetime(DayMonthYearHourMinute) }} Uhr
|
||||
</td>
|
||||
<td>
|
||||
{{ availability.comment.as_deref().unwrap_or_default() }}
|
||||
</td>
|
||||
<td>
|
||||
{% if availability.user_id == user.id || user.role == Role::Admin || user.role == Role::AreaManager %}
|
||||
<div class="buttons is-right">
|
||||
<a class="button is-primary is-light" href="/availability/edit/{{ availability.id }}"
|
||||
title="Verfügbarkeit bearbeiten">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#edit" />
|
||||
</svg>
|
||||
</a>
|
||||
<button class="button is-danger is-light" hx-delete="/availability/delete/{{ availability.id }}"
|
||||
hx-target="closest tr" hx-swap="delete" hx-trigger="confirmed"
|
||||
title="Verfügbarkeit löschen">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#x-circle" />
|
||||
</svg>
|
||||
</button>
|
||||
{% if user.role == Role::Admin || (user.role == Role::AreaManager && user.area_id ==
|
||||
availability.user.as_ref().unwrap().area_id) %}
|
||||
{% include "calendar_cross_areal_button.html" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% include "calendar_tr_availability.html" %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1,8 +0,0 @@
|
||||
<button class="button is-link is-light" hx-swap="outerHTML"
|
||||
hx-put="/availability/{{ availability.id }}/make{% if availability.cross_areal %}Non{% endif %}CrossAreal"
|
||||
title="{% if availability.cross_areal %}nur im Hauptbereich{% else %}Bereichsübergreifend{% endif %} verfügbar machen">
|
||||
<svg class="icon">
|
||||
<use
|
||||
href="/static/feather-sprite.svg#{% if availability.cross_areal %}home{% else %}globe{% endif %}" />
|
||||
</svg>
|
||||
</button>
|
45
web/templates/calendar_tr_availability.html
Normal file
45
web/templates/calendar_tr_availability.html
Normal file
@ -0,0 +1,45 @@
|
||||
<tr>
|
||||
<td>{{ u.name }}</td>
|
||||
<td>
|
||||
{{ u.function|show_tree|safe }}
|
||||
</td>
|
||||
<td>
|
||||
{{ availability.start|fmt_datetime(HourMinute) }} Uhr bis
|
||||
{{ availability.end|fmt_datetime(DayMonthYearHourMinute) }} Uhr
|
||||
</td>
|
||||
<td>
|
||||
{{- availability.comment.as_deref().unwrap_or_default() -}}
|
||||
</td>
|
||||
{%- if user.role == Role::AreaManager || user.role == Role::Admin %}
|
||||
<td>{% if availability.cross_areal %}ja{% else %}nein{% endif %}</td>
|
||||
{% endif -%}
|
||||
<td>
|
||||
{% if availability.user_id == user.id || user.role == Role::Admin || user.role == Role::AreaManager %}
|
||||
<div class="buttons is-right">
|
||||
<a class="button is-primary is-light" href="/availability/edit/{{ availability.id }}"
|
||||
title="Verfügbarkeit bearbeiten">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#edit" />
|
||||
</svg>
|
||||
</a>
|
||||
<button class="button is-danger is-light" hx-delete="/availability/delete/{{ availability.id }}"
|
||||
hx-target="closest tr" hx-swap="delete" hx-trigger="confirmed"
|
||||
title="Verfügbarkeit löschen">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#x-circle" />
|
||||
</svg>
|
||||
</button>
|
||||
{% if user.role == Role::Admin || (user.role == Role::AreaManager && user.area_id == u.area_id) %}
|
||||
<button class="button is-link is-light" hx-swap="outerHTML" hx-target="closest tr"
|
||||
hx-put="/availability/{{ availability.id }}/make{% if availability.cross_areal %}Non{% endif %}CrossAreal"
|
||||
title="{% if availability.cross_areal %}nur im Hauptbereich{% else %}Bereichsübergreifend{% endif %} verfügbar machen">
|
||||
<svg class="icon">
|
||||
<use
|
||||
href="/static/feather-sprite.svg#{% if availability.cross_areal %}home{% else %}globe{% endif %}" />
|
||||
</svg>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
Loading…
x
Reference in New Issue
Block a user