Staging
This commit is contained in:
		
							
								
								
									
										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) { |     if(bodyContainerElement) { | ||||||
|       bodyContainerElement.innerHTML = ''; |       bodyContainerElement.innerHTML = ''; | ||||||
|       bodyContainerElement.append(bodyElement); |       bodyContainerElement.append(bodyElement); | ||||||
|  |  | ||||||
|  |       addRelationMagic(bodyElement); | ||||||
|     } |     } | ||||||
|     if(triggerElement.dataset.day) { |     if(triggerElement.dataset.day) { | ||||||
|       let hiddenElement = <HTMLInputElement>bodyElement.querySelector('.day-js'); |       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() { | function replaceStrings() { | ||||||
|   const weekdays = document.querySelectorAll('.weekday-js'); |   const weekdays = document.querySelectorAll('.weekday-js'); | ||||||
|   Array.prototype.forEach.call(weekdays, (weekday: HTMLElement) => { |   Array.prototype.forEach.call(weekdays, (weekday: HTMLElement) => { | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ export default defineConfig({ | |||||||
|     rollupOptions: { |     rollupOptions: { | ||||||
|       input: { |       input: { | ||||||
|         main: './main.ts', |         main: './main.ts', | ||||||
|  |         logbook: './logbook.ts', | ||||||
|         // Example for more entry points |         // Example for more entry points | ||||||
|         // test: './src/test.ts', |         // test: './src/test.ts', | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -204,6 +204,7 @@ ORDER BY departure DESC | |||||||
|         let mut tx = db.begin().await.unwrap(); |         let mut tx = db.begin().await.unwrap(); | ||||||
|  |  | ||||||
|         let departure = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap(); |         let departure = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap(); | ||||||
|  |         println!("@@@@@@ {:?}", log.arrival); | ||||||
|         let arrival = log |         let arrival = log | ||||||
|             .arrival |             .arrival | ||||||
|             .map(|a| NaiveDateTime::parse_from_str(&a, "%Y-%m-%dT%H:%M").unwrap()); |             .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 response = req.dispatch().await; | ||||||
|  |  | ||||||
|         let text = response.into_string().await.unwrap(); |         let text = response.into_string().await.unwrap(); | ||||||
|  |         println!("{text:?}"); | ||||||
|         assert!(text.contains("Logbuch")); |         assert!(text.contains("Logbuch")); | ||||||
|         assert!(text.contains("Bootsname: Joe")); |         assert!(text.contains("Joe")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[sqlx::test] |     #[sqlx::test] | ||||||
| @@ -361,7 +362,7 @@ mod test { | |||||||
|  |  | ||||||
|         let text = response.into_string().await.unwrap(); |         let text = response.into_string().await.unwrap(); | ||||||
|         assert!(text.contains("Logbuch")); |         assert!(text.contains("Logbuch")); | ||||||
|         assert!(text.contains("Bootsname: Joe")); |         assert!(text.contains("Joe")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[sqlx::test] |     #[sqlx::test] | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
| 		{{ macros::checkbox(label='Gäste erlauben', name='tripdetails.allow_guests') }} | 		{{ macros::checkbox(label='Gäste erlauben', name='tripdetails.allow_guests') }} | ||||||
| 		{{ macros::checkbox(label='Immer anzeigen', name='tripdetails.always_show') }} | 		{{ macros::checkbox(label='Immer anzeigen', name='tripdetails.always_show') }} | ||||||
| 		{{ macros::input(label='Anmerkungen', name='tripdetails.notes', type='input') }} | 		{{ 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"/> | 		<input value="Erstellen" class="w-full btn btn-primary" type="submit"/> | ||||||
| 	</form> | 	</form> | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| 		{{ macros::checkbox(label='Gäste erlauben', name='allow_guests') }} | 		{{ macros::checkbox(label='Gäste erlauben', name='allow_guests') }} | ||||||
| 		{{ macros::checkbox(label='Immer anzeigen', name='always_show') }} | 		{{ macros::checkbox(label='Immer anzeigen', name='always_show') }} | ||||||
| 		{{ macros::input(label='Anmerkungen', name='notes', type='input') }} | 		{{ 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"/> | 		<input value="Erstellen" class="w-full btn btn-primary" type="submit"/> | ||||||
| 	</form> | 	</form> | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ | |||||||
| 			{{ macros::input(label="Anzahl Sitze", name="amount_seats", type="number", required=true, min=1) }} | 			{{ 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="Baujahr", name="year_built", type="number", min=1950, max=2050) }} | ||||||
| 			{{ macros::input(label="Bootsbauer", name="boatbuilder", type="text") }} | 			{{ macros::input(label="Bootsbauer", name="boatbuilder", type="text") }} | ||||||
| 			{{ macros::select(data=locations, label='location', select_name='location_id', selected_id=1) }} | 			{{ macros::select(data=locations, label='location', name='location_id', selected_id=1) }} | ||||||
| 			{{ macros::select(data=users, label='users', select_name='owner', default="Vereinsboot") }} | 			{{ macros::select(data=users, label='users', name='owner', default="Vereinsboot") }} | ||||||
| 			{{ macros::checkbox(label="Steuerperson steuert nur", name="default_shipmaster_only_steering")}} | 			{{ macros::checkbox(label="Steuerperson steuert nur", name="default_shipmaster_only_steering")}} | ||||||
| 			{{ macros::checkbox(label="Skull", name="skull", checked=true)}} | 			{{ macros::checkbox(label="Skull", name="skull", checked=true)}} | ||||||
| 			{{ macros::checkbox(label="Externes Boot (anderer Verein)", name="external")}} | 			{{ macros::checkbox(label="Externes Boot (anderer Verein)", name="external")}} | ||||||
| @@ -29,8 +29,8 @@ | |||||||
| 			<div class="grid md:grid-cols-3"> | 			<div class="grid md:grid-cols-3"> | ||||||
| 				{{ macros::input(label='Name', name='name', type='text', value=boat.name) }} | 				{{ 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::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=locations, label='location', 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=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='Baujahr', name='year_built', type='number', min=1950, value=boat.year_built) }} | ||||||
| 				{{ macros::input(label='Bootsbauer', name='boatbuilder', type='text', value=boat.boatbuilder) }} | 				{{ 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) }} | 				{{ 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) %} | {% macro new(only_ones, allow_any_shipmaster, shipmaster) %} | ||||||
|   <form action="/log" method="post" id="form" class="grid grid-cols-2 gap-3"> | 	<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) }} | 		{{ log::boat_select(only_ones=only_ones) }} | ||||||
|  |  | ||||||
| 	  {% if allow_any_shipmaster %} | 		{% if allow_any_shipmaster %} | ||||||
| 	    <select name="shipmaster" id="shipmaster" class="input rounded-md h-10"> | 			<select name="shipmaster" id="shipmaster" class="input rounded-md h-10"> | ||||||
| 	      <optgroup label="Steuerleute"> | 				<optgroup label="Steuerleute"> | ||||||
| 	      	{% for cox in coxes %} | 					{% for cox in coxes %} | ||||||
|                      <option value="{{ cox.id }}" {% if cox.id == shipmaster%} selected {% endif %}>{{ cox.name }}</option> | 						<option value="{{ cox.id }}" {% if cox.id == shipmaster%} selected {% endif %}>{{ cox.name }}</option> | ||||||
| 	             {% endfor %} | 					{% endfor %} | ||||||
| 	      </optgroup> | 				</optgroup> | ||||||
| 	      <optgroup label="Mitglieder"> | 				<optgroup label="Mitglieder"> | ||||||
| 	      	{% for user in users | filter(attribute="is_cox", value=false) %} | 					{% for user in users | filter(attribute="is_cox", value=false) %} | ||||||
|                      <option value="{{ user.id }}" {% if user.id == shipmaster%} selected {% endif %}>{{ user.name }}</option> | 						<option value="{{ user.id }}" {% if user.id == shipmaster%} selected {% endif %}>{{ user.name }}</option> | ||||||
| 	             {% endfor %} | 					{% endfor %} | ||||||
| 	      </optgroup> | 				</optgroup> | ||||||
|             </select> | 			</select> | ||||||
| 	 {% else %} | 		{% else %} | ||||||
| 	 	<input type="hidden" name="shipmaster" value="{{shipmaster}}" /> | 			<input type="hidden" name="shipmaster" value="{{shipmaster}}"/> | ||||||
| 	 {% endif %} | 		{% endif %} | ||||||
| 	{% if not only_ones %} | 		{% if not only_ones %} | ||||||
|           {{ macros::checkbox(label='handgesteuert', name='shipmaster_only_steering') }} | 			{{ macros::checkbox(label='handgesteuert', name='shipmaster_only_steering') }} | ||||||
| 	{% endif %} | 		{% endif %} | ||||||
|  |  | ||||||
| 	{% if not only_ones %} | 		{% if not only_ones %} | ||||||
| 		{{ log::rower_select(id="newrower", selected=[], class="col-span-2") }} | 			{{ log::rower_select(id="newrower", selected=[], class="col-span-2") }} | ||||||
| 	{% endif %} | 		{% endif %} | ||||||
|  |  | ||||||
|   <div></div> | 		<div></div> | ||||||
|  |  | ||||||
|   {{ macros::input(label='Abfahrtszeit', name='departure', type='datetime-local', required=true) }} | 		<div> | ||||||
|   {{ macros::input(label='Ankunftszeit', name='arrival', type='datetime-local') }} | 			<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> | 		<div> | ||||||
|     <label for="destination" class="small text-gray-600">Ziel</label> | 			<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'); | 			<input type="search" class="input rounded-md set-distance-js" list="destinations" placeholder="Destination" name="destination" id="destination" data-relation="distance_in_km"> | ||||||
|   var dataList = document.getElementById('destinations'); | 			<datalist id="destinations"> | ||||||
|   var selectedValue = inputElement.value; | 				{% for distance in distances %} | ||||||
|   for (var i = 0; i < dataList.options.length; i++) { | 					<option value="{{ distance.0 }}" distance={{ distance.1 }}/> | ||||||
|     if (dataList.options[i].value === selectedValue) { | 				{% endfor %} | ||||||
|       var distance = dataList.options[i].getAttribute('distance'); | 			</datalist> | ||||||
|       document.getElementById('distance_in_km').value = distance; | 		</div> | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|   }"> |  | ||||||
| 	<datalist id="destinations"> |  | ||||||
|         {% for distance in distances %} |  | ||||||
|   		<option value="{{ distance.0 }}" distance={{ distance.1 }} /> |  | ||||||
|         {% endfor %} |  | ||||||
| 	</datalist> |  | ||||||
|   </div> |  | ||||||
|  |  | ||||||
|   <div class="relative"> | 		<div class="relative"> | ||||||
|   	{{ macros::input(label="Distanz", name="distance_in_km", type="number", min=1) }} | 			{{ 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> | 			<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> | 		</div> | ||||||
| 	{{ macros::input(label="Kommentar", name="comments", type="text", wrapper_class="col-span-2") }} | 		{{ macros::input(label="Kommentar", name="comments", type="text", wrapper_class="col-span-2") }} | ||||||
|  |  | ||||||
|   <div class="col-span-2"> | 		<div class="col-span-2"> | ||||||
|     <label for="logtype" class=" small text-gray-600 ">Typ</label> | 			<label for="logtype" class=" small text-gray-600 ">Typ</label> | ||||||
|   	{{ macros::select(data=logtypes, select_name='logtype', default="Normal") }} | 			{{ macros::select(data=logtypes, name='logtype', default="Normal") }} | ||||||
|   </div> | 		</div> | ||||||
| 	<input type="submit" value="Ausfahrt starten" class="btn btn-primary w-full col-span-2 m-auto" /> | 		<input type="submit" value="Ausfahrt starten" class="btn btn-primary w-full col-span-2 m-auto"/> | ||||||
| 	 | 	</form> | ||||||
| 	<script> |  | ||||||
|   const currentDate = new Date(); |  | ||||||
|   const localTime = new Date(currentDate.getTime() - (currentDate.getTimezoneOffset() * 60000)); |  | ||||||
|   const formattedDate = localTime.toISOString().slice(0, 16); |  | ||||||
|  |  | ||||||
|   // 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> |  | ||||||
| {% endmacro new %} | {% 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) %} | {% macro boat_select(only_ones) %} | ||||||
| 	  {% if not 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") }} | 		{{ macros::select(data=boats, name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"], class="col-span-2") }} | ||||||
| 	  {% else %} | 	{% else %} | ||||||
| 	  	{% set ones = boats | filter(attribute="amount_seats", value=1) %} | 		{% 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") }} | 		{{ macros::select(data=ones, name='boat_id', display=["name", " (","amount_seats", " x)"], extras=["default_shipmaster_only_steering", "amount_seats"], class="col-span-2") }} | ||||||
| 	  {% endif %} | 	{% 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> |  | ||||||
| {% endmacro boat_select %} | {% 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) %} | {% macro show(log, state, allowed_to_close=false, only_ones) %} | ||||||
|     <div class="grid grid-cols-1 gap-3 mb-3 w-full"> | 	<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="pt-2 px-3 {% if not loop.first %} border-t {% endif %}"> | ||||||
|         <div class="w-full"> | 			<div class="w-full"> | ||||||
|           <div class="flex justify-between"> | 				<div class="flex justify-between"> | ||||||
|             <div> | 					<div> | ||||||
|               <strong class="text-primary-900"> | 						<strong class="text-primary-900"> | ||||||
|                 {{ log.departure_timestamp | date(format="%H:%M") }} Uhr  | 							{{ log.departure_timestamp | date(format="%H:%M") }} | ||||||
|               </strong>  | 							Uhr | ||||||
|               <small class="text-gray-600">({{ log.boat.name }})</small> | 						</strong> | ||||||
|             </div> | 						<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"> | 					<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 | 						Details | ||||||
|             </a> | 					</a> | ||||||
|           </div> | 				</div> | ||||||
|  |  | ||||||
|           <div> | 				<div> | ||||||
|             {% if allowed_to_close and state == "on_water" %} | 					{% 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"> | 						<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 | 							Beenden | ||||||
|             </a> | 						</a> | ||||||
|             {% endif %} | 					{% endif %} | ||||||
|           </div> | 				</div> | ||||||
|  |  | ||||||
|         <div class="hidden"> | 				<div class="hidden"> | ||||||
|             {% if allowed_to_close and state == "on_water" %} | 					{% if allowed_to_close and state == "on_water" %} | ||||||
|             <div id="close{{ log.id }}"> | 						<div id="close{{ log.id }}"> | ||||||
|               {{ log::home(log=log, only_ones=only_ones) }} | 							{{ log::home(log=log, only_ones=only_ones) }} | ||||||
|             </div> | 						</div> | ||||||
|             {% endif %} | 					{% endif %} | ||||||
|             <div id="log{{ log.id }}"> | 					<div id="log{{ log.id }}"> | ||||||
|               {% if log.destination %}  | 						{% if log.destination %} | ||||||
|                 {{ log.destination }} | 							{{ log.destination }} | ||||||
|               {% endif %} | 						{% endif %} | ||||||
|  |  | ||||||
|               {% for cox in coxes %} | 						{% for cox in coxes %} | ||||||
|                   {% if cox.id == log.shipmaster %} | 							{% if cox.id == log.shipmaster %} | ||||||
|                     <p> | 								<p> | ||||||
|                       <strong>{{ cox.name }}</strong> | 									<strong>{{ cox.name }}</strong> | ||||||
|                     </p> | 								</p> | ||||||
|                   {% endif %} | 							{% endif %} | ||||||
|               {% endfor %} | 						{% endfor %} | ||||||
|  |  | ||||||
|               {% for rower in log.rowers %} | 						{% for rower in log.rowers %} | ||||||
|                 <p>{{ rower.name }}</p> | 							<p>{{ rower.name }}</p> | ||||||
|               {% endfor %} | 						{% endfor %} | ||||||
|             </div> | 					</div> | ||||||
|           </div> | 				</div> | ||||||
|         </div> | 			</div> | ||||||
|       </div> | 		</div> | ||||||
|     </div> | 	</div> | ||||||
| {% endmacro show %} | {% endmacro show %} | ||||||
|  |  | ||||||
| {% macro show_old(log, state, allowed_to_close=false, only_ones) %} | {% macro show_old(log, state, allowed_to_close=false, only_ones) %} | ||||||
|     Bootsname: {{ log.boat.name }}<br /> | 	Bootsname: | ||||||
|     Schiffsführer: {{ log.shipmaster_user.name }}<br /> | 	{{ log.boat.name }}<br/> | ||||||
|     {% if log.shipmaster_only_steering %} | 	Schiffsführer: | ||||||
|       Schiffsführer steuert nur | 	{{ log.shipmaster_user.name }}<br/> | ||||||
|     {% endif %} | 	{% if log.shipmaster_only_steering %} | ||||||
|     Weggefahren: {{ log.departure }}<br /> | 		Schiffsführer steuert nur | ||||||
|     {% if state == "completed" %} | 	{% endif %} | ||||||
|         Angekommen: {{ log.arrival}}<br /> | 	Weggefahren: | ||||||
|     {% endif %} | 	{{ log.departure }}<br/> | ||||||
|     {% set amount_rowers = log.rowers | length %} | 	{% if state == "completed" %} | ||||||
|     {% set amount_guests = log.boat.amount_seats - amount_rowers -1 %} | 		Angekommen: | ||||||
|     {% if allowed_to_close and state == "on_water" %} | 		{{ log.arrival}}<br/> | ||||||
|       {{ log::home(log=log, only_ones=only_ones) }} | 	{% endif %} | ||||||
|     {% else %} | 	{% set amount_rowers = log.rowers | length %} | ||||||
|       Ziel: {{ log.destination }}<br /> | 	{% set amount_guests = log.boat.amount_seats - amount_rowers -1 %} | ||||||
|       {% if state == "completed" %} | 	{% if allowed_to_close and state == "on_water" %} | ||||||
|           Km: {{ log.distance_in_km }}<br /> | 		{{ log::home(log=log, only_ones=only_ones) }} | ||||||
|       {% endif %} | 	{% else %} | ||||||
|       {% if log.comments %} | 		Ziel: | ||||||
|         Kommentare: {{ log.comments }}<br /> | 		{{ log.destination }}<br/> | ||||||
|       {% endif %} | 		{% if state == "completed" %} | ||||||
|       {% if log.logtype %} | 			Km: | ||||||
| 	Logtype: {{ log.logtype }}<br /> | 			{{ log.distance_in_km }}<br/> | ||||||
|       {% endif %} | 		{% endif %} | ||||||
|       {% if amount_guests > 0 or log.rowers | length > 0 %} | 		{% if log.comments %} | ||||||
|       Ruderer:  | 			Kommentare: | ||||||
|       {% endif %} | 			{{ log.comments }}<br/> | ||||||
|       {% if amount_guests > 0 %} | 		{% endif %} | ||||||
|               {{ amount_guests }} Gäste (ohne Account) | 		{% if log.logtype %} | ||||||
|       {% endif %} | 			Logtype: | ||||||
|       {% for rower in log.rowers %} | 			{{ log.logtype }}<br/> | ||||||
|       	{{ rower.name }} | 		{% endif %} | ||||||
|       {% endfor %} | 		{% if amount_guests > 0 or log.rowers | length > 0 %} | ||||||
|     {% endif %} | 			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 %} | {% endmacro show_old %} | ||||||
|  |  | ||||||
| {% macro home(log, only_ones) %} | {% macro home(log, only_ones) %} | ||||||
| <form class="grid grid-cols-1 gap-3" action="/log/{{log.id}}" method="post"> | 	<form class="grid grid-cols-1 gap-3" action="/log/{{log.id}}" method="post"> | ||||||
|     {% if not only_ones %} | 		{% 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> | ||||||
|  |  | ||||||
|     {% endif %} | 			<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 class="relative"> | 		</div> | ||||||
|         <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> |  | ||||||
|  |  | ||||||
|     <div class="relative"> | 		<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) }} | 			{{ 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> | 			<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> | 		</div> | ||||||
|  |  | ||||||
|     {{ macros::input(label="Kommentar", name="comments", type="text", value=log.comments) }} | 		{{ macros::input(label="Kommentar", name="comments", id="comments" ~ log.id, type="text", value=log.comments, class="rounded-md change-id-js") }} | ||||||
|  |  | ||||||
|     <div> | 		<div> | ||||||
|       <label for="logtype" class=" small text-gray-600 ">Typ</label> | 			<label for="logtype" class=" small text-gray-600 ">Typ</label> | ||||||
|       {{ macros::select(data=logtypes, select_name='logtype', default="Normal", selected_id=log.logtype) }} | 			{{ macros::select(data=logtypes, name="logtype", id="logtype" ~ log.id, default="Normal", selected_id=log.logtype, class="rounded-md change-id-js") }} | ||||||
|     </div> | 		</div> | ||||||
|         <input class="btn btn-primary" type="submit" value="Ausfahrt beenden"/> | 		<input class="btn btn-primary" type="submit" value="Ausfahrt beenden"/> | ||||||
|       </form> | 	</form> | ||||||
| {% endmacro home %} | {% endmacro home %} | ||||||
|  |  | ||||||
|  |  | ||||||
| {% 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 %} |  | ||||||
|   | |||||||
| @@ -74,11 +74,11 @@ | |||||||
| 	</label> | 	</label> | ||||||
| {% endmacro checkbox %} | {% 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 == '' %} | 	{% if display == '' %} | ||||||
| 		{% set display = ["name"] %} | 		{% set display = ["name"] %} | ||||||
| 	{% endif %} | 	{% 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 %} | 		{% if default %} | ||||||
| 			<option selected value>{{ default }}</option> | 			<option selected value>{{ default }}</option> | ||||||
| 		{% endif %} | 		{% endif %} | ||||||
|   | |||||||
| @@ -239,7 +239,7 @@ | |||||||
| 															{{ macros::input(label='Anmerkungen', name='notes', type='input', value=trip.notes) }} | 															{{ 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='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::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"/> | 															<input value="Speichern" class="btn btn-primary" type="submit"/> | ||||||
| 														</form> | 														</form> | ||||||
|   | |||||||
| @@ -39,4 +39,6 @@ | |||||||
| </div> | </div> | ||||||
|  |  | ||||||
| {% include "dynamics/sidebar" %} | {% include "dynamics/sidebar" %} | ||||||
|  |  | ||||||
|  | <script src="/public/logbook.js"></script> | ||||||
| {% endblock content%} | {% endblock content%} | ||||||
|   | |||||||
| @@ -11,33 +11,36 @@ | |||||||
| 	<div class="w-full"> | 	<div class="w-full"> | ||||||
| 		<h1 class="h1">Logbuch</h1> | 		<h1 class="h1">Logbuch</h1> | ||||||
|  |  | ||||||
|   <div class="w-full grid md:grid-cols-5 gap-3 mt-5"> | 		<div class="w-full grid md:grid-cols-5 gap-3 mt-5"> | ||||||
|     <div class="bg-white rounded-md hidden md:block shadow"> | 			<div class="bg-white rounded-md hidden md:block shadow"> | ||||||
|       <h2 class="h2">Boote</h2> | 				<h2 class="h2">Boote</h2> | ||||||
|  |  | ||||||
|       <div> | 				<div> | ||||||
|         {{ log::show_boats(only_ones=false) }} | 					{{ log::show_boats(only_ones=false) }} | ||||||
|       </div> | 				</div> | ||||||
|     </div> | 			</div> | ||||||
|     <div class="md:col-span-3 bg-white rounded-md shadow"> | 			<div class="md:col-span-3 bg-white rounded-md shadow"> | ||||||
|       <h2 class="h2">Neue Ausfahrt</h2> | 				<h2 class="h2">Neue Ausfahrt</h2> | ||||||
|       <div class="p-3"> | 				<div class="p-3"> | ||||||
|         {{ log::new(only_ones=loggedin_user.is_cox==false, allow_any_shipmaster=loggedin_user.is_cox, shipmaster=loggedin_user.id) }} | 					{{ log::new(only_ones=loggedin_user.is_cox==false, allow_any_shipmaster=loggedin_user.is_cox, shipmaster=loggedin_user.id) }} | ||||||
|       </div> | 				</div> | ||||||
|     </div> | 			</div> | ||||||
|     <div class="bg-white rounded-md shadow"> | 			<div class="bg-white rounded-md shadow"> | ||||||
|       <h2 class="h2">Am Wasser</h2> | 				<h2 class="h2">Am Wasser</h2> | ||||||
|  |  | ||||||
|       {% for log in on_water %} | 				{% for log in on_water %} | ||||||
|         {% if log.shipmaster == loggedin_user.id %} | 					{% if log.shipmaster == loggedin_user.id %} | ||||||
|           {{ log::show(log=log, state="on_water", allowed_to_close=true, only_ones=loggedin_user.is_cox==false) }} | 						{{ log::show(log=log, state="on_water", allowed_to_close=true, only_ones=loggedin_user.is_cox==false) }} | ||||||
|         {% else %} | 					{% else %} | ||||||
|           {{ log::show(log=log, state="on_water", only_ones=true) }} | 						{{ log::show(log=log, state="on_water", only_ones=true) }} | ||||||
|         {% endif %} | 					{% endif %} | ||||||
|       {% endfor %} | 				{% endfor %} | ||||||
|     </div> | 			</div> | ||||||
|   </div> | 		</div> | ||||||
| </div> | 	</div> | ||||||
|  |  | ||||||
| {% include "dynamics/sidebar" %} | 	{% include "dynamics/sidebar" %} | ||||||
|  |  | ||||||
|  | 	<script src="/public/logbook.js"></script> | ||||||
|  | 	<script src="/public/js/multiselect-dropdown.js"></script> | ||||||
| {% endblock content%} | {% endblock content%} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user