Refactor code
This commit is contained in:
parent
709411ce5c
commit
a1dc92defd
33
frontend/logbook.ts
Normal file
33
frontend/logbook.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/*document.addEventListener('DOMContentLoaded', function() {
|
||||
setDistance('.set-distance-js');
|
||||
});
|
||||
|
||||
function setDistance(selector: string) {
|
||||
const fields = document.querySelectorAll(selector);
|
||||
if(fields) {
|
||||
Array.prototype.forEach.call(fields, (field: HTMLInputElement) => {
|
||||
if(field.dataset.relation){
|
||||
const relatedField = <HTMLInputElement>document.getElementById(field.dataset.relation);
|
||||
|
||||
if(relatedField) {
|
||||
field.addEventListener('input', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const dataList = <HTMLDataListElement>document.getElementById('destinations');
|
||||
if(dataList) {
|
||||
var option = Array.prototype.find.call(dataList.options, function(option) {
|
||||
return option.value === field.value;
|
||||
});
|
||||
|
||||
// Get distance
|
||||
const distance = option.getAttribute('distance');
|
||||
if(distance) relatedField.value = distance;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
*/
|
||||
export {}
|
@ -202,9 +202,22 @@ function initTripSidebar(triggerElement: HTMLElement) {
|
||||
}
|
||||
});
|
||||
|
||||
const prefixedContent = <NodeListOf<HTMLElement>>bodyElement.querySelectorAll('.change-id-js');
|
||||
Array.prototype.forEach.call(prefixedContent, (content: HTMLElement) => {
|
||||
if(content) {
|
||||
content.id += 'js';
|
||||
|
||||
if(content.dataset.relation){
|
||||
content.dataset.relation += 'js';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(bodyContainerElement) {
|
||||
bodyContainerElement.innerHTML = '';
|
||||
bodyContainerElement.append(bodyElement);
|
||||
|
||||
addRelationMagic(bodyElement);
|
||||
}
|
||||
if(triggerElement.dataset.day) {
|
||||
let hiddenElement = <HTMLInputElement>bodyElement.querySelector('.day-js');
|
||||
@ -220,6 +233,33 @@ function initTripSidebar(triggerElement: HTMLElement) {
|
||||
}
|
||||
}
|
||||
|
||||
function addRelationMagic(bodyElement: HTMLElement) {
|
||||
const fields = bodyElement.querySelectorAll('.set-distance-js');
|
||||
if(fields) {
|
||||
Array.prototype.forEach.call(fields, (field: HTMLInputElement) => {
|
||||
if(field.dataset.relation){
|
||||
const relatedField = <HTMLInputElement>bodyElement.querySelector('#' + field.dataset.relation);
|
||||
|
||||
if(relatedField) {
|
||||
field.addEventListener('input', (e) => {
|
||||
e.preventDefault();
|
||||
const dataList = <HTMLDataListElement>document.getElementById('destinations');
|
||||
if(dataList) {
|
||||
var option = Array.prototype.find.call(dataList.options, function(option) {
|
||||
return option.value === field.value;
|
||||
});
|
||||
|
||||
// Get distance
|
||||
const distance = option.getAttribute('distance');
|
||||
if(distance) relatedField.value = distance;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function replaceStrings() {
|
||||
const weekdays = document.querySelectorAll('.weekday-js');
|
||||
Array.prototype.forEach.call(weekdays, (weekday: HTMLElement) => {
|
||||
|
@ -17,6 +17,7 @@ export default defineConfig({
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: './main.ts',
|
||||
logbook: './logbook.ts',
|
||||
// Example for more entry points
|
||||
// test: './src/test.ts',
|
||||
},
|
||||
|
@ -204,6 +204,7 @@ ORDER BY departure DESC
|
||||
let mut tx = db.begin().await.unwrap();
|
||||
|
||||
let departure = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap();
|
||||
println!("@@@@@@ {:?}", log.arrival);
|
||||
let arrival = log
|
||||
.arrival
|
||||
.map(|a| NaiveDateTime::parse_from_str(&a, "%Y-%m-%dT%H:%M").unwrap());
|
||||
|
@ -341,8 +341,9 @@ mod test {
|
||||
let response = req.dispatch().await;
|
||||
|
||||
let text = response.into_string().await.unwrap();
|
||||
println!("{text:?}");
|
||||
assert!(text.contains("Logbuch"));
|
||||
assert!(text.contains("Bootsname: Joe"));
|
||||
assert!(text.contains("Joe"));
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
@ -361,7 +362,7 @@ mod test {
|
||||
|
||||
let text = response.into_string().await.unwrap();
|
||||
assert!(text.contains("Logbuch"));
|
||||
assert!(text.contains("Bootsname: Joe"));
|
||||
assert!(text.contains("Joe"));
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
|
@ -10,7 +10,7 @@
|
||||
{{ macros::checkbox(label='Gäste erlauben', name='tripdetails.allow_guests') }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='tripdetails.always_show') }}
|
||||
{{ macros::input(label='Anmerkungen', name='tripdetails.notes', type='input') }}
|
||||
{{ macros::select(data=trip_types, select_name='tripdetails.trip_type', default='Reguläre Ausfahrt') }}
|
||||
{{ macros::select(data=trip_types, name='tripdetails.trip_type', default='Reguläre Ausfahrt') }}
|
||||
|
||||
<input value="Erstellen" class="w-full btn btn-primary" type="submit"/>
|
||||
</form>
|
||||
|
@ -8,7 +8,7 @@
|
||||
{{ macros::checkbox(label='Gäste erlauben', name='allow_guests') }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='always_show') }}
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input') }}
|
||||
{{ macros::select(data=trip_types, select_name='trip_type', default='Reguläre Ausfahrt') }}
|
||||
{{ macros::select(data=trip_types, name='trip_type', default='Reguläre Ausfahrt') }}
|
||||
|
||||
<input value="Erstellen" class="w-full btn btn-primary" type="submit"/>
|
||||
</form>
|
||||
|
@ -8,8 +8,8 @@
|
||||
{{ macros::input(label="Anzahl Sitze", name="amount_seats", type="number", required=true, min=1) }}
|
||||
{{ macros::input(label="Baujahr", name="year_built", type="number", min=1950, max=2050) }}
|
||||
{{ macros::input(label="Bootsbauer", name="boatbuilder", type="text") }}
|
||||
{{ macros::select(data=locations, label='location', select_name='location_id', selected_id=1) }}
|
||||
{{ macros::select(data=users, label='users', select_name='owner', default="Vereinsboot") }}
|
||||
{{ macros::select(data=locations, label='location', name='location_id', selected_id=1) }}
|
||||
{{ macros::select(data=users, label='users', name='owner', default="Vereinsboot") }}
|
||||
{{ macros::checkbox(label="Steuerperson steuert nur", name="default_shipmaster_only_steering")}}
|
||||
{{ macros::checkbox(label="Skull", name="skull", checked=true)}}
|
||||
{{ macros::checkbox(label="Externes Boot (anderer Verein)", name="external")}}
|
||||
@ -29,8 +29,8 @@
|
||||
<div class="grid md:grid-cols-3">
|
||||
{{ macros::input(label='Name', name='name', type='text', value=boat.name) }}
|
||||
{{ macros::input(label='Amount Seats', name='amount_seats', type='number', min=0, value=boat.amount_seats) }}
|
||||
{{ macros::select(data=locations, label='location', select_name='location_id', selected_id=boat.location_id) }}
|
||||
{{ macros::select(data=users, label='users', select_name='owner', selected_id=boat.owner, default="Vereinsboot") }}
|
||||
{{ macros::select(data=locations, label='location', name='location_id', selected_id=boat.location_id) }}
|
||||
{{ macros::select(data=users, label='users', name='owner', selected_id=boat.owner, default="Vereinsboot") }}
|
||||
{{ macros::input(label='Baujahr', name='year_built', type='number', min=1950, value=boat.year_built) }}
|
||||
{{ macros::input(label='Bootsbauer', name='boatbuilder', type='text', value=boat.boatbuilder) }}
|
||||
{{ macros::checkbox(label='default_shipmaster_only_steering', name='default_shipmaster_only_steering', id=uuid , checked=boat.default_shipmaster_only_steering) }}
|
||||
|
@ -1,297 +1,252 @@
|
||||
{# Shows a fancy, optional lists of boats. They are grouped by boat category.
|
||||
|
||||
Inputs: boats
|
||||
Parameters: only_ones: if set, only 1x boats are shown
|
||||
#}
|
||||
{% macro show_boats(only_ones) %}
|
||||
{% if only_ones %}
|
||||
{% set_global boats = boats | filter(attribute="amount_seats", value=1) %}
|
||||
{% endif %}
|
||||
{% for amount_seats, grouped_boats in boats | group_by(attribute="amount_seats") %}
|
||||
<div class="pb-2">
|
||||
<div class="bg-gray-100 text-primary-950 text-center text-sm mb-2">
|
||||
<strong>{{ amount_seats }}x</strong>
|
||||
</div>
|
||||
{% for boat in grouped_boats %}
|
||||
<div id="boat-{{ boat.id }}" class="px-3" {% if boat.damage != 'locked' %} onclick="document.getElementById('boat_id').value={{ boat.id }}; document.getElementById('newrower-max_rower_allowed').innerHTML={{ boat.amount_seats }}; document.getElementById('departure').value = new Date().toISOString().slice(0,16);" {% endif %}>
|
||||
<span class="status-damage status-damage-{{ boat.damage }}"></span>
|
||||
<span {% if boat.damage == 'locked' or boat.on_water %} class="opacity-50" {% endif %}>{{ boat.name }}
|
||||
{% if boat.owner %}
|
||||
<span class="opacity-50">(privat)</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endmacro show_boats %}
|
||||
|
||||
{# Shows the form for creating a new logbook entry. #}
|
||||
{% macro new(only_ones, allow_any_shipmaster, shipmaster) %}
|
||||
<form action="/log" method="post" id="form" class="grid grid-cols-2 gap-3">
|
||||
{{ log::boat_select(only_ones=only_ones) }}
|
||||
<form action="/log" method="post" id="form" class="grid grid-cols-2 gap-3" onsubmit="Array.from(this.elements).forEach(e=>!e.value.trim()&&(e.disabled=true));">
|
||||
{{ log::boat_select(only_ones=only_ones) }}
|
||||
|
||||
{% if allow_any_shipmaster %}
|
||||
<select name="shipmaster" id="shipmaster" class="input rounded-md h-10">
|
||||
<optgroup label="Steuerleute">
|
||||
{% for cox in coxes %}
|
||||
<option value="{{ cox.id }}" {% if cox.id == shipmaster%} selected {% endif %}>{{ cox.name }}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
<optgroup label="Mitglieder">
|
||||
{% for user in users | filter(attribute="is_cox", value=false) %}
|
||||
<option value="{{ user.id }}" {% if user.id == shipmaster%} selected {% endif %}>{{ user.name }}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="hidden" name="shipmaster" value="{{shipmaster}}" />
|
||||
{% endif %}
|
||||
{% if not only_ones %}
|
||||
{{ macros::checkbox(label='handgesteuert', name='shipmaster_only_steering') }}
|
||||
{% endif %}
|
||||
|
||||
{% if not only_ones %}
|
||||
{{ log::rower_select(id="newrower", selected=[], class="col-span-2") }}
|
||||
{% endif %}
|
||||
{% if allow_any_shipmaster %}
|
||||
<select name="shipmaster" id="shipmaster" class="input rounded-md h-10">
|
||||
<optgroup label="Steuerleute">
|
||||
{% for cox in coxes %}
|
||||
<option value="{{ cox.id }}" {% if cox.id == shipmaster%} selected {% endif %}>{{ cox.name }}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
<optgroup label="Mitglieder">
|
||||
{% for user in users | filter(attribute="is_cox", value=false) %}
|
||||
<option value="{{ user.id }}" {% if user.id == shipmaster%} selected {% endif %}>{{ user.name }}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="hidden" name="shipmaster" value="{{shipmaster}}"/>
|
||||
{% endif %}
|
||||
{% if not only_ones %}
|
||||
{{ macros::checkbox(label='handgesteuert', name='shipmaster_only_steering') }}
|
||||
{% endif %}
|
||||
|
||||
<div></div>
|
||||
{% if not only_ones %}
|
||||
{{ log::rower_select(id="newrower", selected=[], class="col-span-2") }}
|
||||
{% endif %}
|
||||
|
||||
{{ macros::input(label='Abfahrtszeit', name='departure', type='datetime-local', required=true) }}
|
||||
{{ macros::input(label='Ankunftszeit', name='arrival', type='datetime-local') }}
|
||||
<div></div>
|
||||
|
||||
<div>
|
||||
<label for="destination" class="small text-gray-600">Ziel</label>
|
||||
<input type="search" class="input rounded-md" list="destinations" placeholder="Destination" name="destination" id="destination" oninput="var inputElement = document.getElementById('destination');
|
||||
var dataList = document.getElementById('destinations');
|
||||
var selectedValue = inputElement.value;
|
||||
for (var i = 0; i < dataList.options.length; i++) {
|
||||
if (dataList.options[i].value === selectedValue) {
|
||||
var distance = dataList.options[i].getAttribute('distance');
|
||||
document.getElementById('distance_in_km').value = distance;
|
||||
break;
|
||||
}
|
||||
}">
|
||||
<datalist id="destinations">
|
||||
{% for distance in distances %}
|
||||
<option value="{{ distance.0 }}" distance={{ distance.1 }} />
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
</div>
|
||||
<div>
|
||||
<label for="destination" class="small text-gray-600">Ziel</label>
|
||||
<input type="search" class="input rounded-md" list="destinations" placeholder="Destination" name="destination" id="destination">
|
||||
<datalist id="destinations">
|
||||
{% for distance in distances %}
|
||||
<option value="{{ distance.0 }}" distance={{ distance.1 }}/>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
</div>
|
||||
{{ macros::input(label='Abfahrtszeit', name='departure', type='datetime-local', required=true) }}
|
||||
{{ macros::input(label='Ankunftszeit', name='arrival', type='datetime-local') }}
|
||||
|
||||
<div class="relative">
|
||||
{{ macros::input(label="Distanz", name="distance_in_km", type="number", min=1) }}
|
||||
<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", type="text", wrapper_class="col-span-2") }}
|
||||
<div>
|
||||
<label for="destination" class="small text-gray-600">Ziel</label>
|
||||
<input type="search" class="input rounded-md set-distance-js" list="destinations" placeholder="Destination" name="destination" id="destination" data-relation="distance_in_km">
|
||||
<datalist id="destinations">
|
||||
{% for distance in distances %}
|
||||
<option value="{{ distance.0 }}" distance={{ distance.1 }}/>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
</div>
|
||||
|
||||
<div class="col-span-2">
|
||||
<label for="logtype" class=" small text-gray-600 ">Typ</label>
|
||||
{{ macros::select(data=logtypes, select_name='logtype', default="Normal") }}
|
||||
</div>
|
||||
<input type="submit" value="Ausfahrt starten" class="btn btn-primary w-full col-span-2 m-auto" />
|
||||
|
||||
<script>
|
||||
const currentDate = new Date();
|
||||
const localTime = new Date(currentDate.getTime() - (currentDate.getTimezoneOffset() * 60000));
|
||||
const formattedDate = localTime.toISOString().slice(0, 16);
|
||||
<div class="relative">
|
||||
{{ macros::input(label="Distanz", name="distance_in_km", type="number", min=1) }}
|
||||
<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", type="text", wrapper_class="col-span-2") }}
|
||||
|
||||
// Set the formatted string as the value of the input field
|
||||
document.getElementById("departure").value = formattedDate;
|
||||
</script>
|
||||
</form>
|
||||
|
||||
<script src="/public/js/multiselect-dropdown.js" ></script>
|
||||
<script>
|
||||
document.getElementById('form').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
for(let optional_elem of ["arrival", "distance_in_km", "comments", "logtype"]){
|
||||
let myInput = document.getElementById(optional_elem);
|
||||
if (myInput.value === '') {
|
||||
myInput.removeAttribute('name');
|
||||
}
|
||||
}
|
||||
this.submit();
|
||||
});
|
||||
</script>
|
||||
<div class="col-span-2">
|
||||
<label for="logtype" class=" small text-gray-600 ">Typ</label>
|
||||
{{ macros::select(data=logtypes, name='logtype', default="Normal") }}
|
||||
</div>
|
||||
<input type="submit" value="Ausfahrt starten" class="btn btn-primary w-full col-span-2 m-auto"/>
|
||||
</form>
|
||||
{% endmacro new %}
|
||||
|
||||
{% macro show_boats(only_ones) %}
|
||||
{% if only_ones %}
|
||||
{% set_global boats = boats | filter(attribute="amount_seats", value=1) %}
|
||||
{% endif %}
|
||||
{% for amount_seats, grouped_boats in boats | group_by(attribute="amount_seats") %}
|
||||
<div class="pb-2">
|
||||
<div class="bg-gray-100 text-primary-950 text-center text-sm mb-2">
|
||||
<strong>{{ amount_seats }}x</strong>
|
||||
</div>
|
||||
{% for boat in grouped_boats %}
|
||||
<div id="boat-{{ boat.id }}" {% if boat.damage != 'locked' %} onclick="document.getElementById('boat_id').value='{{ boat.id }}';updateElementsBasedOnSelectedOption()"{% endif %} class="px-3">
|
||||
<span class="status-damage status-damage-{{ boat.damage }}"></span>
|
||||
<span {% if boat.damage == 'locked' or boat.on_water %} class="opacity-50" {% endif %}>{{ boat.name }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<script>
|
||||
function updateElementsBasedOnSelectedOption() {
|
||||
var selectElement = document.getElementById('boat_id');
|
||||
var selectedOption = selectElement.selectedOptions[0];
|
||||
var shipmaster_only_steering = selectedOption.getAttribute("extra-default_shipmaster_only_steering") === 'true';
|
||||
document.getElementById('shipmaster_only_steering').checked = shipmaster_only_steering;
|
||||
document.getElementById('newrower-max_rower_allowed').innerHTML = selectedOption.getAttribute("extra-amount_seats");
|
||||
|
||||
console.log(selectElement.selectedOptions[0]);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.getElementById('boat_id').addEventListener('change', updateElementsBasedOnSelectedOption);
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', updateElementsBasedOnSelectedOption);
|
||||
</script>
|
||||
{% endmacro boats %}
|
||||
|
||||
{% macro boat_select(only_ones) %}
|
||||
{% if not only_ones %}
|
||||
{{ macros::select(data=boats, select_name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"], class="col-span-2") }}
|
||||
{% else %}
|
||||
{% set ones = boats | filter(attribute="amount_seats", value=1) %}
|
||||
{{ macros::select(data=ones, select_name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"], class="col-span-2") }}
|
||||
{% endif %}
|
||||
<script>
|
||||
function updateElementsBasedOnSelectedOption() {
|
||||
var selectElement = document.getElementById('boat_id');
|
||||
var selectedOption = selectElement.selectedOptions[0];
|
||||
var shipmaster_only_steering = selectedOption.getAttribute("extra-default_shipmaster_only_steering") === 'true';
|
||||
document.getElementById('shipmaster_only_steering').checked = shipmaster_only_steering;
|
||||
document.getElementById('newrower-max_rower_allowed').innerHTML = selectedOption.getAttribute("extra-amount_seats");
|
||||
}
|
||||
|
||||
document.getElementById('boat_id').addEventListener('change', updateElementsBasedOnSelectedOption);
|
||||
document.addEventListener('DOMContentLoaded', updateElementsBasedOnSelectedOption);
|
||||
</script>
|
||||
{% if not only_ones %}
|
||||
{{ macros::select(data=boats, name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"], class="col-span-2") }}
|
||||
{% else %}
|
||||
{% set ones = boats | filter(attribute="amount_seats", value=1) %}
|
||||
{{ macros::select(data=ones, name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"], class="col-span-2") }}
|
||||
{% endif %}
|
||||
{% endmacro boat_select %}
|
||||
|
||||
{% macro rower_select(id, selected, amount_seats='', class='') %}
|
||||
<div class="{{ class }}">
|
||||
<select style="width: 100px;" multiple="multiple" name="rowers[]" multiselect-search="true" id="{{id}}" class="w-full">
|
||||
{% for user in users %}
|
||||
{% set_global sel = false %}
|
||||
{% for rower in selected %}
|
||||
{% if rower.id == user.id %}
|
||||
{% set_global sel = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<option value="{{ user.id }}" {% if sel %} selected {% endif %}>{{user.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<span id="{{id}}-amount_rower_selected"></span>
|
||||
<span id="{{id}}-max_rower_allowed">{{amount_seats}}</span>
|
||||
Ruderer auszuwählen
|
||||
</div>
|
||||
{% endmacro rower_select %}
|
||||
|
||||
{% macro show(log, state, allowed_to_close=false, only_ones) %}
|
||||
<div class="grid grid-cols-1 gap-3 mb-3 w-full">
|
||||
<div class="pt-2 px-3 {% if not loop.first %} border-t {% endif %}">
|
||||
<div class="w-full">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<strong class="text-primary-900">
|
||||
{{ log.departure_timestamp | date(format="%H:%M") }} Uhr
|
||||
</strong>
|
||||
<small class="text-gray-600">({{ log.boat.name }})</small>
|
||||
</div>
|
||||
|
||||
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure_timestamp | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#log{{ log.id }}" class="inline-block link-primary mr-3">
|
||||
Details
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure_timestamp | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#close{{ log.id }}" class="btn btn-dark w-full mt-3">
|
||||
Beenden
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-3 mb-3 w-full">
|
||||
<div class="pt-2 px-3 {% if not loop.first %} border-t {% endif %}">
|
||||
<div class="w-full">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<strong class="text-primary-900">
|
||||
{{ log.departure_timestamp | date(format="%H:%M") }}
|
||||
Uhr
|
||||
</strong>
|
||||
<small class="text-gray-600">({{ log.boat.name }})</small>
|
||||
</div>
|
||||
|
||||
<div class="hidden">
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
<div id="close{{ log.id }}">
|
||||
{{ log::home(log=log, only_ones=only_ones) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="log{{ log.id }}">
|
||||
{% if log.destination %}
|
||||
{{ log.destination }}
|
||||
{% endif %}
|
||||
|
||||
{% for cox in coxes %}
|
||||
{% if cox.id == log.shipmaster %}
|
||||
<p>
|
||||
<strong>{{ cox.name }}</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure_timestamp | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#log{{ log.id }}" class="inline-block link-primary mr-3">
|
||||
Details
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% for rower in log.rowers %}
|
||||
<p>{{ rower.name }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro show %}
|
||||
<div>
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>{{ log.departure_timestamp | date(format="%H:%M") }} Uhr</strong> ({{ log.boat.name }})" data-body="#close{{ log.id }}" class="btn btn-dark w-full mt-3">
|
||||
Beenden
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="hidden">
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
<div id="close{{ log.id }}">
|
||||
{{ log::home(log=log, only_ones=only_ones) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="log{{ log.id }}">
|
||||
{% if log.destination %}
|
||||
{{ log.destination }}
|
||||
{% endif %}
|
||||
|
||||
{% for cox in coxes %}
|
||||
{% if cox.id == log.shipmaster %}
|
||||
<p>
|
||||
<strong>{{ cox.name }}</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for rower in log.rowers %}
|
||||
<p>{{ rower.name }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro show %}
|
||||
|
||||
{% macro show_old(log, state, allowed_to_close=false, only_ones) %}
|
||||
Bootsname: {{ log.boat.name }}<br />
|
||||
Schiffsführer: {{ log.shipmaster_user.name }}<br />
|
||||
{% if log.shipmaster_only_steering %}
|
||||
Schiffsführer steuert nur
|
||||
{% endif %}
|
||||
Weggefahren: {{ log.departure }}<br />
|
||||
{% if state == "completed" %}
|
||||
Angekommen: {{ log.arrival}}<br />
|
||||
{% endif %}
|
||||
{% set amount_rowers = log.rowers | length %}
|
||||
{% set amount_guests = log.boat.amount_seats - amount_rowers -1 %}
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
{{ log::home(log=log, only_ones=only_ones) }}
|
||||
{% else %}
|
||||
Ziel: {{ log.destination }}<br />
|
||||
{% if state == "completed" %}
|
||||
Km: {{ log.distance_in_km }}<br />
|
||||
{% endif %}
|
||||
{% if log.comments %}
|
||||
Kommentare: {{ log.comments }}<br />
|
||||
{% endif %}
|
||||
{% if log.logtype %}
|
||||
Logtype: {{ log.logtype }}<br />
|
||||
{% endif %}
|
||||
{% if amount_guests > 0 or log.rowers | length > 0 %}
|
||||
Ruderer:
|
||||
{% endif %}
|
||||
{% if amount_guests > 0 %}
|
||||
{{ amount_guests }} Gäste (ohne Account)
|
||||
{% endif %}
|
||||
{% for rower in log.rowers %}
|
||||
{{ rower.name }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endmacro show_old %}
|
||||
Bootsname:
|
||||
{{ log.boat.name }}<br/>
|
||||
Schiffsführer:
|
||||
{{ log.shipmaster_user.name }}<br/>
|
||||
{% if log.shipmaster_only_steering %}
|
||||
Schiffsführer steuert nur
|
||||
{% endif %}
|
||||
Weggefahren:
|
||||
{{ log.departure }}<br/>
|
||||
{% if state == "completed" %}
|
||||
Angekommen:
|
||||
{{ log.arrival}}<br/>
|
||||
{% endif %}
|
||||
{% set amount_rowers = log.rowers | length %}
|
||||
{% set amount_guests = log.boat.amount_seats - amount_rowers -1 %}
|
||||
{% if allowed_to_close and state == "on_water" %}
|
||||
{{ log::home(log=log, only_ones=only_ones) }}
|
||||
{% else %}
|
||||
Ziel:
|
||||
{{ log.destination }}<br/>
|
||||
{% if state == "completed" %}
|
||||
Km:
|
||||
{{ log.distance_in_km }}<br/>
|
||||
{% endif %}
|
||||
{% if log.comments %}
|
||||
Kommentare:
|
||||
{{ log.comments }}<br/>
|
||||
{% endif %}
|
||||
{% if log.logtype %}
|
||||
Logtype:
|
||||
{{ log.logtype }}<br/>
|
||||
{% endif %}
|
||||
{% if amount_guests > 0 or log.rowers | length > 0 %}
|
||||
Ruderer:
|
||||
{% endif %}
|
||||
{% if amount_guests > 0 %}
|
||||
{{ amount_guests }}
|
||||
Gäste (ohne Account)
|
||||
{% endif %}
|
||||
{% for rower in log.rowers %}
|
||||
{{ rower.name }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endmacro show_old %}
|
||||
|
||||
{% macro home(log, only_ones) %}
|
||||
<form class="grid grid-cols-1 gap-3" action="/log/{{log.id}}" method="post">
|
||||
{% if not only_ones %}
|
||||
|
||||
{% endif %}
|
||||
<div class="relative">
|
||||
<label for="destination" class="small text-gray-600">Ziel</label>
|
||||
<input class="input rounded-md" type="search" list="destinations" placeholder="Destination" required="required", id="destination-home" name="destination" value="{{log.destination}}" oninput="var inputElement = document.getElementById('destination-home');
|
||||
var dataList = document.getElementById('destinations');
|
||||
var selectedValue = inputElement.value;
|
||||
for (var i = 0; i < dataList.options.length; i++) {
|
||||
if (dataList.options[i].value === selectedValue) {
|
||||
var distance = dataList.options[i].getAttribute('distance');
|
||||
document.getElementById('distance_in_km_home').value = distance;
|
||||
break;
|
||||
}
|
||||
}">
|
||||
</div>
|
||||
<form class="grid grid-cols-1 gap-3" action="/log/{{log.id}}" method="post">
|
||||
{% if not only_ones %}
|
||||
{{ log::rower_select(id="rowers"~log.id, selected=log.rowers, amount_seats=log.boat.amount_seats) }}
|
||||
{% endif %}
|
||||
<div class="relative">
|
||||
<label for="destination" class="small text-gray-600">Ziel</label>
|
||||
|
||||
<div class="relative">
|
||||
{{ macros::input(label="Distanz", name="distance_in_km", id="distance_in_km_home", type="number", min=0, value=log.distance_in_km, required=true) }}
|
||||
<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", type="text", value=log.comments) }}
|
||||
<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}}"/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="logtype" class=" small text-gray-600 ">Typ</label>
|
||||
{{ macros::select(data=logtypes, select_name='logtype', default="Normal", selected_id=log.logtype) }}
|
||||
</div>
|
||||
<input class="btn btn-primary" type="submit" value="Ausfahrt beenden"/>
|
||||
</form>
|
||||
{% endmacro home %}
|
||||
<div class="relative">
|
||||
{{ macros::input(label="Distanz", name="distance_in_km", id="distance_in_km" ~ log.id , type="number", min=0, value=log.distance_in_km, required=true, class="rounded-md change-id-js") }}
|
||||
<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") }}
|
||||
|
||||
{% macro rower_select(id, selected, amount_seats='', class='') %}
|
||||
<div class="{{ class }}">
|
||||
<select multiple="multiple" name="rower[]" multiselect-search="true" multiselect-max-items="8" id="{{id}}" onclick="updateSelectedRowersCount{{id}}()" onblur="updateSelectedRowersCount{{id}}()" class="w-full">
|
||||
{% for user in users %}
|
||||
{% set_global sel = false %}
|
||||
{% for rower in selected %}
|
||||
{% if rower.id == user.id %}
|
||||
{% set_global sel = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<option value="{{ user.id }}" {% if sel %}selected{% endif %} onmousedown="event.preventDefault();this.selected = !this.selected; return false;">{{user.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<script>
|
||||
function updateSelectedRowersCount{{id}}() {
|
||||
document.getElementById('{{id}}-amount_rower_selected').textContent = document.getElementById('{{id}}').selectedOptions.length+1;
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', updateSelectedRowersCount{{id}});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span id="{{id}}-amount_rower_selected"></span>/<span id="{{id}}-max_rower_allowed">{{amount_seats}}</span> Ruderer ausgewählt
|
||||
</div>
|
||||
{% endmacro rower_select %}
|
||||
<div>
|
||||
<label for="logtype" class=" small text-gray-600 ">Typ</label>
|
||||
{{ macros::select(data=logtypes, name="logtype", id="logtype" ~ log.id, default="Normal", selected_id=log.logtype, class="rounded-md change-id-js") }}
|
||||
</div>
|
||||
<input class="btn btn-primary" type="submit" value="Ausfahrt beenden"/>
|
||||
</form>
|
||||
{% endmacro home %}
|
||||
|
@ -74,11 +74,11 @@
|
||||
</label>
|
||||
{% endmacro checkbox %}
|
||||
|
||||
{% macro select(data, select_name='trip_type', default='', selected_id='', display='', extras='', class='') %}
|
||||
{% macro select(data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='') %}
|
||||
{% if display == '' %}
|
||||
{% set display = ["name"] %}
|
||||
{% endif %}
|
||||
<select name="{{ select_name }}" id="{{ select_name }}" class="input rounded-md h-10 {{ class }}">
|
||||
<select name="{{ name }}" {% if id %} id="{{ id }}" {% else %} id="{{ name }}" {% endif %} class="input rounded-md h-10 {{ class }}">
|
||||
{% if default %}
|
||||
<option selected value>{{ default }}</option>
|
||||
{% endif %}
|
||||
|
@ -239,7 +239,7 @@
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input', value=trip.notes) }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='always_show', id=trip.id,checked=trip.always_show) }}
|
||||
{{ macros::checkbox(label='Gesperrt', name='is_locked', id=trip.id,checked=trip.is_locked) }}
|
||||
{{ macros::select(select_name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id) }}
|
||||
{{ macros::select(name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id) }}
|
||||
|
||||
<input value="Speichern" class="btn btn-primary" type="submit"/>
|
||||
</form>
|
||||
|
@ -39,4 +39,6 @@
|
||||
</div>
|
||||
|
||||
{% include "dynamics/sidebar" %}
|
||||
|
||||
<script src="/public/logbook.js"></script>
|
||||
{% endblock content%}
|
||||
|
@ -11,33 +11,36 @@
|
||||
<div class="w-full">
|
||||
<h1 class="h1">Logbuch</h1>
|
||||
|
||||
<div class="w-full grid md:grid-cols-5 gap-3 mt-5">
|
||||
<div class="bg-white rounded-md hidden md:block shadow">
|
||||
<h2 class="h2">Boote</h2>
|
||||
|
||||
<div>
|
||||
{{ log::show_boats(only_ones=false) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:col-span-3 bg-white rounded-md shadow">
|
||||
<h2 class="h2">Neue Ausfahrt</h2>
|
||||
<div class="p-3">
|
||||
{{ log::new(only_ones=loggedin_user.is_cox==false, allow_any_shipmaster=loggedin_user.is_cox, shipmaster=loggedin_user.id) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-md shadow">
|
||||
<h2 class="h2">Am Wasser</h2>
|
||||
<div class="w-full grid md:grid-cols-5 gap-3 mt-5">
|
||||
<div class="bg-white rounded-md hidden md:block shadow">
|
||||
<h2 class="h2">Boote</h2>
|
||||
|
||||
{% for log in on_water %}
|
||||
{% if log.shipmaster == loggedin_user.id %}
|
||||
{{ log::show(log=log, state="on_water", allowed_to_close=true, only_ones=loggedin_user.is_cox==false) }}
|
||||
{% else %}
|
||||
{{ log::show(log=log, state="on_water", only_ones=true) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{ log::show_boats(only_ones=false) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:col-span-3 bg-white rounded-md shadow">
|
||||
<h2 class="h2">Neue Ausfahrt</h2>
|
||||
<div class="p-3">
|
||||
{{ log::new(only_ones=loggedin_user.is_cox==false, allow_any_shipmaster=loggedin_user.is_cox, shipmaster=loggedin_user.id) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-md shadow">
|
||||
<h2 class="h2">Am Wasser</h2>
|
||||
|
||||
{% include "dynamics/sidebar" %}
|
||||
{% for log in on_water %}
|
||||
{% if log.shipmaster == loggedin_user.id %}
|
||||
{{ log::show(log=log, state="on_water", allowed_to_close=true, only_ones=loggedin_user.is_cox==false) }}
|
||||
{% else %}
|
||||
{{ log::show(log=log, state="on_water", only_ones=true) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "dynamics/sidebar" %}
|
||||
|
||||
<script src="/public/logbook.js"></script>
|
||||
<script src="/public/js/multiselect-dropdown.js"></script>
|
||||
{% endblock content%}
|
||||
|
Loading…
Reference in New Issue
Block a user