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
|
expression: disable_body
|
||||||
snapshot_kind: text
|
snapshot_kind: text
|
||||||
---
|
---
|
||||||
<button class="button is-link is-light" hx-swap="outerHTML"
|
<tr>
|
||||||
hx-put="/availability/1/makeCrossAreal"
|
<td>Max Mustermann</td>
|
||||||
title="Bereichsübergreifend verfügbar machen">
|
<td>
|
||||||
<svg class="icon">
|
<div class="tags"><span class="tag is-primary is-light">Posten</span></div>
|
||||||
<use
|
</td>
|
||||||
href="/static/feather-sprite.svg#globe" />
|
<td>
|
||||||
</svg>
|
10:00 Uhr bis
|
||||||
</button>
|
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
|
expression: enable_body
|
||||||
snapshot_kind: text
|
snapshot_kind: text
|
||||||
---
|
---
|
||||||
<button class="button is-link is-light" hx-swap="outerHTML"
|
<tr>
|
||||||
hx-put="/availability/1/makeNonCrossAreal"
|
<td>Max Mustermann</td>
|
||||||
title="nur im Hauptbereich verfügbar machen">
|
<td>
|
||||||
<svg class="icon">
|
<div class="tags"><span class="tag is-primary is-light">Posten</span></div>
|
||||||
<use
|
</td>
|
||||||
href="/static/feather-sprite.svg#home" />
|
<td>
|
||||||
</svg>
|
10:00 Uhr bis
|
||||||
</button>
|
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 actix_web::{web, HttpResponse, Responder};
|
||||||
use askama::Template;
|
use askama::{filters::urlencode, Template};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
endpoints::IdPath,
|
endpoints::IdPath,
|
||||||
utils::{ApplicationError, TemplateResponse},
|
filters,
|
||||||
|
utils::{
|
||||||
|
ApplicationError,
|
||||||
|
DateTimeFormat::{DayMonthYearHourMinute, HourMinute},
|
||||||
|
TemplateResponse,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use brass_db::models::{Assignment, Availability, Role, User};
|
use brass_db::models::{Assignment, Availability, Role, User};
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "calendar_cross_areal_button.html")]
|
#[template(path = "calendar_tr_availability.html")]
|
||||||
struct CalendarPartialCrossArealButtonTemplate {
|
struct CalendarAvailabilityTableRowTemplate {
|
||||||
|
user: User,
|
||||||
availability: Availability,
|
availability: Availability,
|
||||||
|
u: User,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::put("/availability/{id}/makeNonCrossAreal")]
|
#[actix_web::put("/availability/{id}/makeNonCrossAreal")]
|
||||||
@ -60,7 +68,7 @@ async fn handle_cross_areal(
|
|||||||
let trigger = json!({
|
let trigger = json!({
|
||||||
"showToast": {
|
"showToast": {
|
||||||
"type": "danger",
|
"type": "danger",
|
||||||
"message": "Verfügbarkeit bereits verplant!"
|
"message": urlencode("Verfügbarkeit bereits verplant!").unwrap().to_string()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.to_string();
|
.to_string();
|
||||||
@ -75,7 +83,13 @@ async fn handle_cross_areal(
|
|||||||
availability.cross_areal = 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()?)
|
Ok(template.to_response()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +116,9 @@ mod tests {
|
|||||||
RequestConfig::new("/availability/1/makeCrossAreal").with_role(Role::AreaManager);
|
RequestConfig::new("/availability/1/makeCrossAreal").with_role(Role::AreaManager);
|
||||||
create_test_login_user(&context.db_pool, &config).await;
|
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(
|
Availability::create(
|
||||||
&context.db_pool,
|
&context.db_pool,
|
||||||
2,
|
2,
|
||||||
|
@ -60,7 +60,7 @@ setThemeSwitcherIconTo(isCurrentlyLight ? "moon" : "sun");
|
|||||||
htmx.on("showToast", (e) => {
|
htmx.on("showToast", (e) => {
|
||||||
const toast = document.getElementById("toast");
|
const toast = document.getElementById("toast");
|
||||||
const toastProgress = document.getElementById("toast-progress");
|
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}`);
|
toast.classList.add(`is-${e.detail.type}`);
|
||||||
toastProgress.classList.add(`has-background-${e.detail.type}-90`)
|
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">
|
<input type="hidden" name="enddate" value="{{ enddate.as_ref().unwrap_or(date) }}" id="enddate">
|
||||||
|
|
||||||
{% if other_users.len() != 0 %}
|
{% 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 is-horizontal">
|
||||||
<div class="field-label">
|
<div class="field-label">
|
||||||
<label class="label">Nutzer</label>
|
<label class="label">Nutzer</label>
|
||||||
@ -21,12 +23,13 @@
|
|||||||
<div class="field is-narrow">
|
<div class="field is-narrow">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<div class="select is-fullwidth">
|
<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 %}
|
{% 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") }}>
|
{{ (other_user.is_some() && *other_user.as_ref().unwrap()==u.id)|cond_show("selected") }}>
|
||||||
{{ u.name }}
|
{{ 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>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
@ -305,48 +305,16 @@
|
|||||||
<th>Funktion</th>
|
<th>Funktion</th>
|
||||||
<th>Zeitraum</th>
|
<th>Zeitraum</th>
|
||||||
<th>Kommentar</th>
|
<th>Kommentar</th>
|
||||||
|
{% if user.role == Role::AreaManager || user.role == Role::Admin %}
|
||||||
|
<th>bereichsübergreifend</th>
|
||||||
|
{% endif %}
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for availability in availabilities %}
|
{% for availability in availabilities %}
|
||||||
{% let u = availability.user.as_ref().unwrap() %}
|
{% let u = availability.user.as_ref().unwrap() %}
|
||||||
<tr>
|
{% include "calendar_tr_availability.html" %}
|
||||||
<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>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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