frontend for new db

This commit is contained in:
philipp 2023-10-30 13:39:58 +01:00
parent e256d7274d
commit 2d520298e7
4 changed files with 173 additions and 118 deletions

View File

@ -22,11 +22,10 @@ document.addEventListener('DOMContentLoaded', function() {
function setCurrentdate(input: HTMLInputElement) {
if(input) {
const inputElement = document.getElementById("departure") as HTMLInputElement;
const now = new Date();
const formattedDateTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}T${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
inputElement.value = formattedDateTime;
input.value = formattedDateTime;
}
}
@ -53,9 +52,8 @@ function selectBoatChange() {
)[0];
const rowers = Number(originalOption.dataset.amount_seats);
const isShipmasterSteering = originalOption.dataset.default_shipmaster_only_steering;
setMaxAmountRowers(rowers,isShipmasterSteering);
setMaxAmountRowers("newrower", rowers);
return opt;
}
@ -83,51 +81,51 @@ function reloadPage() {
});
}
function setMaxAmountRowers(rowers: number, isShipmasterSteering='false') {
if(choiceObjects['newrower']) {
let curSelection = choiceObjects['newrower'].getValue(true);
function setMaxAmountRowers(name: string, rowers: number) {
if(choiceObjects[name]) {
let curSelection = choiceObjects[name].getValue(true);
let amount_to_delete = (<any>curSelection).length - rowers;
if (amount_to_delete > 0){
let to_delete = (<any>curSelection).slice(-amount_to_delete);
for (let del of to_delete) {
choiceObjects['newrower'].removeActiveItemsByValue(del);
choiceObjects[name].removeActiveItemsByValue(del);
}
}
let input = <HTMLElement>document.querySelector('#newrower');
let input = <HTMLElement>document.querySelector('#'+name);
if(input) {
choiceObjects['newrower'].config.maxItemCount = rowers;
choiceObjects[name].config.maxItemCount = rowers;
if (rowers === 0) {
choiceObjects['newrower'].disable()
choiceObjects[name].disable()
input.parentElement?.parentElement?.parentElement?.classList.add('hidden');
input.parentElement?.parentElement?.parentElement?.classList.add('md:block');
input.parentElement?.parentElement?.parentElement?.classList.add('opacity-50');
} else{
choiceObjects['newrower'].enable();
choiceObjects[name].enable();
input.parentElement?.parentElement?.parentElement?.classList.remove('hidden');
input.parentElement?.parentElement?.parentElement?.classList.remove('md:block');
input.parentElement?.parentElement?.parentElement?.classList.remove('opacity-50');
}
}
let only_steering = <HTMLSelectElement>document.querySelector('#shipmaster_only_steering');
if(only_steering) {
if(isShipmasterSteering == 'true') {
only_steering.removeAttribute('disabled');
only_steering.setAttribute('checked', 'true');
only_steering.parentElement?.parentElement?.parentElement?.classList.remove('hidden');
only_steering.parentElement?.parentElement?.parentElement?.classList.remove('md:block');
only_steering.parentElement?.parentElement?.parentElement?.classList.remove('opacity-50');
} else {
only_steering.setAttribute('disabled', 'disabled');
only_steering.removeAttribute('checked');
only_steering.parentElement?.parentElement?.parentElement?.classList.add('hidden');
only_steering.parentElement?.parentElement?.parentElement?.classList.add('md:block');
only_steering.parentElement?.parentElement?.parentElement?.classList.add('opacity-50');
}
}
//let only_steering = <HTMLSelectElement>document.querySelector('#shipmaster_only_steering');
//if(only_steering) {
// if(isShipmasterSteering == 'true') {
// only_steering.removeAttribute('disabled');
// only_steering.setAttribute('checked', 'true');
// only_steering.parentElement?.parentElement?.parentElement?.classList.remove('hidden');
// only_steering.parentElement?.parentElement?.parentElement?.classList.remove('md:block');
// only_steering.parentElement?.parentElement?.parentElement?.classList.remove('opacity-50');
// } else {
// only_steering.setAttribute('disabled', 'disabled');
// only_steering.removeAttribute('checked');
// only_steering.parentElement?.parentElement?.parentElement?.classList.add('hidden');
// only_steering.parentElement?.parentElement?.parentElement?.classList.add('md:block');
// only_steering.parentElement?.parentElement?.parentElement?.classList.add('opacity-50');
// }
//}
}
}
@ -138,9 +136,8 @@ function initBoatActions() {
select.addEventListener('click', function() {
if(select.dataset.seats) {
const rowers = Number(select.dataset.seats);
const isShipmasterSteering = select.dataset.default_shipmaster_only_steering;
setMaxAmountRowers(rowers, isShipmasterSteering);
setMaxAmountRowers("newrower", rowers);
if (select.dataset.id) {
choiceObjects['boat_id'].setChoiceByValue(select.dataset.id);
@ -174,6 +171,8 @@ interface ChoiceEvent extends Event{
label: string,
customProperties: {
is_cox: boolean,
steers: boolean,
cox_on_boat: boolean,
}
};
}
@ -190,7 +189,50 @@ function initNewChoice(select: HTMLInputElement) {
maxItemText: (maxItemCount) => {
return `Nur ${maxItemCount} Ruderer können hinzugefügt werden`;
},
callbackOnCreateTemplates: function () {
return {
option: ({ label, value, customProperties, active, disabled, }: any) => {
const opt: HTMLOptionElement = Choices.defaults.templates.option.call(
this,
{ label, value, customProperties, active, disabled }
);
// We get the original <option> from choicejs
//const originalOption: HTMLOptionElement = this._presetOptions.filter(
// (option: HTMLOptionElement) => option.value === value
//)[0];
//
//const rowers = Number(originalOption.dataset.amount_seats);
//const isShipmasterSteering = originalOption.dataset.default_shipmaster_only_steering;
//setMaxAmountRowers(select.id, curr_boat_rowers, isShipmasterSteering);
return opt;
}
}
},
callbackOnInit: function() {
this._currentState.items.forEach(function(obj){
if (obj.customProperties && obj.customProperties.is_cox){
const coxSelect = <HTMLSelectElement>document.querySelector('#shipmaster-' + select.id + 'js');
var new_option = new Option(obj.label, obj.value);
if (obj.customProperties.cox_on_boat){
new_option.selected = true;
}
coxSelect.add(new_option);
}
const steeringSelect = <HTMLSelectElement>document.querySelector('#steering_person-' + select.id + 'js');
if (steeringSelect) {
var new_option = new Option(obj.label, obj.value);
if (obj.customProperties && obj.customProperties.steers){
new_option.selected = true;
}
steeringSelect.add(new_option);
}
});
}
});
choiceObjects[select.id] = choice;
select.addEventListener('addItem', function(e) {
const event = e as ChoiceEvent;
@ -198,13 +240,13 @@ function initNewChoice(select: HTMLInputElement) {
const name = event.detail.label;
if (event.detail.customProperties.is_cox) {
const coxSelect = <HTMLSelectElement>document.querySelector('#shipmaster');
const coxSelect = <HTMLSelectElement>document.querySelector('#shipmaster-' + select.id + 'js');
if (coxSelect){
coxSelect.add(new Option(name, user_id));
}
}
const steeringSelect = <HTMLSelectElement>document.querySelector('#steering_person');
const steeringSelect = <HTMLSelectElement>document.querySelector('#steering_person-' + select.id + 'js');
if (steeringSelect) {
steeringSelect.add(new Option(name, user_id));
}
@ -215,7 +257,7 @@ function initNewChoice(select: HTMLInputElement) {
const user_id = event.detail.value;
const coxSelect = <HTMLSelectElement>document.querySelector('#shipmaster');
const coxSelect = <HTMLSelectElement>document.querySelector('#shipmaster-' + select.id + 'js');
if (coxSelect) {
for (var i=0; i<coxSelect.length; i++) {
if (coxSelect.options[i].value == user_id)
@ -223,7 +265,7 @@ function initNewChoice(select: HTMLInputElement) {
}
}
const steeringSelect = <HTMLSelectElement>document.querySelector('#steering_person');
const steeringSelect = <HTMLSelectElement>document.querySelector('#steering_person-' + select.id + 'js');
if (steeringSelect) {
for (var i=0; i<steeringSelect.length; i++) {
if (steeringSelect.options[i].value == user_id)
@ -419,12 +461,6 @@ function initTripSidebar(triggerElement: HTMLElement) {
let bodyElement = <HTMLElement>body.cloneNode(true);
let bodyContainerElement = <HTMLElement>sidebarElement.querySelector('.body-js');
const selects = bodyElement.querySelectorAll('select[multiple]');
if(selects) {
Array.prototype.forEach.call(selects, (select: HTMLInputElement) => {
initNewChoice(select);
});
}
/* Quickfix duplicate ids checkboxes */
const checkboxes = <NodeListOf<HTMLElement>>bodyElement.querySelectorAll('input[type="checkbox"]');
@ -447,6 +483,7 @@ function initTripSidebar(triggerElement: HTMLElement) {
}
});
if(bodyContainerElement) {
bodyContainerElement.innerHTML = '';
bodyContainerElement.append(bodyElement);
@ -464,7 +501,18 @@ function initTripSidebar(triggerElement: HTMLElement) {
if(headerElement) {
headerElement.innerHTML = triggerElement.dataset.header;
}
const selects = bodyElement.querySelectorAll('select[multiple]');
if(selects) {
Array.prototype.forEach.call(selects, (select: HTMLInputElement) => {
initNewChoice(select);
});
}
}
const defaultDateTimes = <NodeListOf<HTMLInputElement>>document.querySelectorAll('.current-date-time');
defaultDateTimes.forEach((defaultDateTime) => {
setCurrentdate(defaultDateTime);
});
}
function addRelationMagic(bodyElement: HTMLElement) {

View File

@ -239,9 +239,17 @@ ORDER BY departure DESC
log: LogToAdd,
created_by_user: &User,
) -> Result<(), LogbookCreateError> {
println!("{log:#?}");
let Some(boat) = Boat::find_by_id(db, log.boat_id).await else {
return Err(LogbookCreateError::BoatNotFound);
};
if let Ok(log_to_finalize) = TryInto::<LogToFinalize>::try_into(log.clone()) {
//TODO: fix clone()
if !boat.shipmaster_allowed(created_by_user).await {
return Err(LogbookCreateError::UserNotAllowedToUseBoat);
}
let mut tx = db.begin().await.unwrap();
let inserted_row = sqlx::query!(
@ -277,10 +285,6 @@ ORDER BY departure DESC
return Err(LogbookCreateError::ArrivalSetButNotRemainingTwo);
}
let Some(boat) = Boat::find_by_id(db, log.boat_id).await else {
return Err(LogbookCreateError::BoatNotFound);
};
if boat.is_locked(db).await {
return Err(LogbookCreateError::BoatLocked);
}

View File

@ -41,8 +41,8 @@
{% if not only_ones %}
{{ log::rower_select(id="newrower", selected=[], class="col-span-4", init=true) }}
{% endif %}
{{ macros::select(label="Schiffsführer", data=[], name='shipmaster', wrapper_class="col-span-2") }}
{{ macros::select(label="Steuerperson", data=[], name='steering_person', wrapper_class="col-span-2") }}
{{ macros::select(label="Schiffsführer", data=[], name='shipmaster', id="shipmaster-newrowerjs", wrapper_class="col-span-2") }}
{{ macros::select(label="Steuerperson", data=[], name='steering_person', id="steering_person-newrowerjs", wrapper_class="col-span-2") }}
{{ macros::input(label='Abfahrtszeit', name='departure', type='datetime-local', required=true, wrapper_class='col-span-2') }}
{{ macros::input(label='Ankunftszeit', name='arrival', type='datetime-local', wrapper_class='col-span-2') }}
<div class="relative col-span-2">
@ -73,7 +73,7 @@
{% endif %}
{% endmacro boat_select %}
{% macro rower_select(id, selected, amount_seats='', class='', init='false') %}
{% macro rower_select(id, selected, amount_seats='', class='', init='false', cox_on_boat='', steering_person_id='') %}
{% if not amount_seats or amount_seats > 1 %}
<div class="{{ class }}">
<label for="{{id}}" class="text-sm text-gray-600 ">Ruderer</label>
@ -85,7 +85,7 @@
{% set_global sel = true %}
{% endif %}
{% endfor %}
<option value="{{ user.id }}" {% if sel %} selected {% endif %} {% if user.on_water %} disabled="disabled" {% endif %} data-custom-properties='{"is_cox": {{ user.is_cox }}}'>
<option value="{{ user.id }}" {% if sel %} selected {% endif %} {% if user.on_water %} disabled="disabled" {% endif %} data-custom-properties='{"is_cox": {{ user.is_cox }}, "steers": {{ user.id == steering_person_id }}, "cox_on_boat": {{ user.id == cox_on_boat}}}'>
{{user.name}}
{% if user.on_water %}
(am Wasser)
@ -107,17 +107,17 @@
{{ log.departure | date(format="%H:%M") }}
Uhr
</strong>
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#log{{ log.id }}" class="text-sm link-primary break-all">
{{ log.boat.name }}
</a>
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#log{{ log.id }}" class="text-sm link-primary break-all">
{{ log.boat.name }}
</a>
</div>
<div>
{% if allowed_to_close and state == "on_water" %}
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#close{{ log.id }}" class="border-0 btn btn-dark text-white flex items-center justify-center ml-3">
{% include "includes/pencil" %}
</a>
{% endif %}
</div>
<div>
{% if allowed_to_close and state == "on_water" %}
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#close{{ log.id }}" class="border-0 btn btn-dark text-white flex items-center justify-center ml-3">
{% include "includes/pencil" %}
</a>
{% endif %}
</div>
</div>
<div class="hidden">
@ -130,31 +130,25 @@
</div>
{% endif %}
<div id="log{{ log.id }}">
{% if log.destination %}
{{ log.destination }}
{% endif %}
{% for user in users %}
{% if user.id == log.shipmaster %}
<p>
<strong>{{ user.name }}</strong>
</p>
{% endif %}
{% endfor %}
{% if log.destination %}
{{ log.destination }}
{% endif %}
{% for rower in log.rowers %}
<p>{{ rower.name }}</p>
<p>{{ rower.name }} {% if rower.id == log.shipmaster %}Schiffsführer {% endif %}{% if rower.id == log.steering_person%}Steuerperson{% endif %}</p>
{# @MB: shipmaster + steering_person could be prettier :') #}
{% endfor %}
{% set amount_rowers = log.rowers | length %}
{% set amount_guests = log.boat.amount_seats - amount_rowers -1 %}
{% set amount_guests = log.boat.amount_seats - amount_rowers -1 %}
{% if amount_guests > 0 %}
Gäste (ohne Account): {{ amount_guests }}
Gäste (ohne Account):
{{ amount_guests }}
{% endif %}
{% if allowed_to_close and state == "on_water" %}
<a href="/log/{{ log.id }}/delete" class="btn btn-alert w-full absolute bottom-0 left-0" style="border-radius: 0;" onclick="return confirm('Willst du diesen Eintrag wirklich löschen? Die Daten gehen verloren');">Löschen</a>
{% endif %}
{% if allowed_to_close and state == "on_water" %}
<a href="/log/{{ log.id }}/delete" class="btn btn-alert w-full absolute bottom-0 left-0" style="border-radius: 0;" onclick="return confirm('Willst du diesen Eintrag wirklich löschen? Die Daten gehen verloren');">Löschen</a>
{% endif %}
</div>
</div>
</div>
@ -219,18 +213,27 @@
{% endmacro show_old %}
{% macro home(log, only_ones) %}
{# @MB: Maaaarieeee, please fix col-span-2 craziness #}
<form class="grid grid-cols-1 gap-3" action="/log/{{log.id}}" method="post">
{% for user in users %}
{% if user.id == log.shipmaster %}
<p>
<strong>{{ user.name }}</strong>
</p>
{% endif %}
{% endfor %}
{% if not only_ones %}
{{ log::rower_select(id="rowers"~log.id, selected=log.rowers, amount_seats=log.boat.amount_seats) }}
{{ log::rower_select(id="rowers"~log.id, selected=log.rowers, amount_seats=log.boat.amount_seats, class="col-span-2", steering_person_id=log.steering_user.id, cox_on_boat=log.shipmaster_user.id) }}
{{ macros::select(label="Schiffsführer", data=[], name='shipmaster', id="shipmaster-rowers"~log.id, wrapper_class="col-span-2", class="change-id-js", selected_id=log.shipmaster_user.id, required=true) }}
{{ macros::select(label="Steuerperson", data=[], name='steering_person', id="steering_person-rowers"~log.id, wrapper_class="col-span-2", class="change-id-js", selected_id=log.steering_user.id, required=true) }}
{% endif %}
<div class="relative">
<div class="col-span-2">
{{ macros::checkbox(label="Handgesteuert", name="shipmaster_only_steering", id="shipmaster_only_steering" ~ log.id , checked=log.shipmaster_only_steering,class="rounded-md change-id-js") }}
</div>
<div class="col-span-2">
{{ macros::input(label='Abfahrtszeit', name='departure', type='datetime-local', required=true, class="change-id-js rounded-md", value=log.departure) }}
</div>
<div class="col-span-2">
{{ macros::input(label='Ankunftszeit', name='arrival', type='datetime-local', required=true, class="change-id-js rounded-md current-date-time") }}
</div>
<div class="col-span-2">
<label for="destination" class="text-sm text-gray-600">Ziel</label>
<input class="input rounded-md set-distance-js change-id-js" type="search" list="destinations" placeholder="Destination" required="required" id="destination{{ log.id }}" name="destination" value="{{log.destination}}" data-relation="distance_in_km{{log.id}}"/>
@ -241,9 +244,9 @@
<span class="absolute right-0 bottom-0 py-1.5 px-2 bg-white border-0 text-gray-600 ring-1 ring-inset ring-gray-300 rounded-br-md rounded-tr-md">km</span>
</div>
{{ macros::input(label="Kommentar", name="comments", id="comments" ~ log.id, type="text", value=log.comments, class="rounded-md change-id-js") }}
{{ macros::select(label="Typ", data=logtypes, name="logtype", id="logtype" ~ log.id, default="Normal", selected_id=log.logtype, class="rounded-md change-id-js") }}
{{ macros::input(label="Kommentar", name="comments", id="comments" ~ log.id, type="text", value=log.comments, class="rounded-md change-id-js", wrapper_class="col-span-2") }}
{{ macros::select(label="Typ", data=logtypes, name="logtype", id="logtype" ~ log.id, default="Normal", selected_id=log.logtype, class="rounded-md change-id-js col-span-2") }}
<input class="btn btn-primary" type="submit" value="Ausfahrt beenden"/>
<input class="btn btn-primary col-span-2" type="submit" value="Ausfahrt beenden"/>
</form>
{% endmacro home %}

View File

@ -78,29 +78,29 @@
</label>
{% endmacro checkbox %}
{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='') %}
{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false) %}
<div class="{{wrapper_class}}">
<label for="{{ name }}" class="text-sm text-gray-600">{{ label }}</label>
{% if display == '' %}
{% set display = ["name"] %}
{% endif %}
<select name="{{ name }}" {% if id %} id="{{ id }}" {% else %} id="{{ name }}" {% endif %} class="input rounded-md {{ class }}">
{% if default %}
<option selected value>{{ default }}</option>
{% endif %}
{% for d in data %}
<option value="{{ d.id }}" {% if d.id == selected_id %} selected {% endif %} {% if extras != '' %} {% for extra in extras %} {% if extra != 'on_water' %} data-{{extra}}={{d[extra]}} {% else %} {% if d[extra] %} disabled {% endif %} {% endif %} {% endfor %} {% endif %}>
{% for displa in display -%}
{%- if d[displa] -%}
{{- d[displa] -}}
{%- else -%}
{{- displa -}}
{%- endif -%}
{%- endfor %}
</option>
{% endfor %}
</select>
</div>
<label for="{{ name }}" class="text-sm text-gray-600">{{ label }}</label>
{% if display == '' %}
{% set display = ["name"] %}
{% endif %}
<select name="{{ name }}" {% if id %} id="{{ id }}" {% else %} id="{{ name }}" {% endif %} class="input rounded-md {{ class }}" {% if required %}required="required"{% endif %}>
{% if default %}
<option selected value>{{ default }}</option>
{% endif %}
{% for d in data %}
<option value="{{ d.id }}" {% if d.id == selected_id %} selected {% endif %} {% if extras != '' %} {% for extra in extras %} {% if extra != 'on_water' %} data- {{extra}}={{d[extra]}} {% else %} {% if d[extra] %} disabled {% endif %} {% endif %} {% endfor %} {% endif %}>
{% for displa in display -%}
{%- if d[displa] -%}
{{- d[displa] -}}
{%- else -%}
{{- displa -}}
{%- endif -%}
{%- endfor %}
</option>
{% endfor %}
</select>
</div>
{% endmacro select %}