ctucx.git: oeffisearch

[nimlang] fast and simple tripplanner

commit f3a0223a8579e81fde074a0d764f87ab3832d9a7
parent aa6e400d2b11b64a3bf26fff5d3612b17d61d988
Author: Milan Pässler <me@pbb.lc>
Date: Fri, 7 Feb 2020 16:41:57 +0100

client/journey: show remarks in modal
4 files changed, 147 insertions(+), 82 deletions(-)
M
client/css/style.css
|
46
++++++++++++++++++++++++++++++++++++++++++----
M
client/js/helpers.js
|
3
++-
M
client/js/journeyView.js
|
176
+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
M
client/js/journeysView.js
|
4
++--
diff --git a/client/css/style.css b/client/css/style.css
@@ -630,11 +630,50 @@ input:focus{
 	}
 
 	.modal-content {
-		-webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
-						box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+		box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
 	}
 }
 
 .cancelled {
 	text-decoration-line: line-through;
-}-
\ No newline at end of file
+}
+
+.showremarks {
+	vertical-align: bottom;
+}
+.remark {
+	vertical-align: middle;
+}
+.showremarks.hint,
+.remark.hint {
+	content: url("../img/info-24px.svg");
+}
+.showremarks.warning,
+.remark.warning {
+	content: url("../img/warning-24px.svg");
+}
+.showremarks.other,
+.remark.other {
+	content: url("../img/help-24px.svg");
+}
+.remarks td {
+	margin: 0 10px;
+	text-align: left;
+	display: block;
+}
+/*.remarks {
+	display: none;
+	position: absolute;
+	z-index: 1;
+}*/
+.remarks {
+	/*background: #000000d0;*/
+	border: 1px solid #ddd;
+	padding: 0;
+	width: 100%;
+	margin: 0;
+	box-shadow: none;
+}
+/*.showremarks:hover+.remarks {
+	display: inline-block;
+}*/
diff --git a/client/js/helpers.js b/client/js/helpers.js
@@ -60,7 +60,8 @@ export const parseDateTime = (timestamp, format) => {
 	}
 };
 
-export const convertMinsToHrsMins = (mins) => {
+export const formatDuration = (duration) => {
+	const mins = duration / 60;
 	const h = Math.floor(mins / 60);
 	const m = mins % 60;
 
diff --git a/client/js/journeyView.js b/client/js/journeyView.js
@@ -1,92 +1,118 @@
 'use strict';
 
-import { showDiv, hideDiv, ElementById, parseDateTime, convertMinsToHrsMins } from './helpers.js';
+import { showDiv, hideDiv, ElementById, parseDateTime, formatDuration } from './helpers.js';
 import { getCache, addCache, ConsoleLog, parseName, ds100Names, t } from './app_functions.js';
+import { showModal } from './overlays.js';
 import { get } from './api.js';
 import { go } from './router.js';
 import { html, render } from './lit-html.js';
 
-const journeyTemplate = (data, requestId, journeyId) => {
-	let departure       = data.legs[0].departure;
-	let arrival         = data.legs[data.legs.length - 1].arrival;
-	let changes         = 0;
+const remarksModalTemplate = (type, remarks) => html`
+	<table class="remarks">
+		${remarks.map(element => html`
+			<tr>
+			<td>
+			  <span class="remark ${type}"></span>
+				<span>${element.text}</span>
+			</td>
+			</tr>
+		`)}
+	</table>
+`;
 
-	let departureTime = departure.prognosedTime ? departure.prognosedTime : departure.plannedTime;
-	let arrivalTime   = arrival.prognosedTime   ? arrival.prognosedTime   : arrival.plannedTime;
-	let duration      = (arrivalTime - departureTime)/60;
+const showRemarksModal = (type, remarks) => {
+	showModal("Remarks", remarksModalTemplate(type, remarks));
+};
+const remarksTemplate = ([type, remarks]) => !!remarks.length ? html`
+	<a class="showremarks ${type}" @click=${() => showRemarksModal(type, remarks)}></a>
+` : '';
+
+const legTemplate = (element) => {
+	const allRemarks = element.remarks || [];
+	const remarks = {
+		"status": allRemarks.filter(r => r.type === 'status'),
+		"hint": allRemarks.filter(r => r.type === 'hint'),
+		"other": allRemarks.filter(r => r.type !== 'status' && r.type !== 'hint'),
+	};
 
-	for (let legKey in data.legs) {
-		let leg = data.legs[legKey];
+	return html`
+		${element.isWalking ? html`
+		<p class="walk">${t('walkinfo', [parseName(element.arrival.point), element.distance])}</p>
+		` : html`
+			${element.isTransfer ? html`
+				<p class="transfer">${t('transferinfo', [parseName(element.arrival.point), element.distance])}</p>
+			` : html`
+				<table>
+					<thead>
+						<tr>
+							<td colspan="4">
+								${element.line.name} ${element.line.additionalName ? '('+element.line.additionalName+')' : ''} → ${element.direction} ${element.cancelled ? html`<b style="color:red;">${t('cancelled-ride')}</b>` : ''}
+								${Object.entries(remarks).map(remarksTemplate)}
+							</td>
+						</tr>
+						<tr>
+							<th>${t('arrival')}</th>
+							<th>${t('departure')}</th>
+							<th>${t('station')}</th>
+							<th>${t('platform')}</th>
+						</tr>
+					</thead>
+					<tbody>
+						${element.stopovers.map(stop => html`
+							<tr class="stop ${stop.cancelled ? 'cancelled' : ''}" @click=${() => {location.href = "https://marudor.de/"+stop.stop.id+"?searchType=hafas"}}>
+								<td>${timeTemplate(stop.arrival)}</td>
+								<td>${timeTemplate(stop.departure)}</td>
+								<td>${stop.stop.name} ${ds100Names(stop.stop.id)}</td>
+								<td>${stopPlatformTemplate(stop)}</td>
+							</tr>
+						`)}
+					</tbody>
+				</table>
+			`}
+		`}
+	`;
+};
 
-		if (leg.isWalking !== false) continue;
+const journeyTemplate = (data, requestId, journeyId) => {
+	const departure       = data.legs[0].departure;
+	const arrival         = data.legs[data.legs.length - 1].arrival;
 
-		changes = changes+1;
-	}
+	const departureTime = departure.prognosedTime ? departure.prognosedTime : departure.plannedTime;
+	const arrivalTime   = arrival.prognosedTime   ? arrival.prognosedTime   : arrival.plannedTime;
+	const duration      = arrivalTime - departureTime;
 
-	return html`
-	<div id="journeyView">
-		<div id="header">
-			<a class="back" href="#/${requestId}"></a>
-			<p>
-				<h2>
-					<span id="fromName2">${parseName(departure.point)}</span>
-					<span> - </span>
-					<span id="toName2">${parseName(arrival.point)}</span>
-				</h2>
-			</p>
-			<p>
-				<b>
-					<span>${t('duration')}: </span>
-					<span id="duration">${convertMinsToHrsMins(duration)}</span>
-					<span> | ${t('changes')}: </span>
-					<span id="changes">${changes-1}</span>
-					<span> | ${t('date')}: </span>
-					<span id="date2">${parseDateTime(departure.plannedTime, 'date')}</span>
-				</b>
-			</p>
-			<div class="reload" id="reload-journey" @click=${() => reloadJourney(requestId, journeyId)}></div>
-		</div>
+	const changes = data.legs.filter(leg => !leg.isWalking).length;
 
-		<div id="connection">
-			${data.legs.map(element => html`
-				${element.isWalking ? html`
-				<p class="walk">${t('walkinfo', [parseName(element.arrival.point), element.distance])}</p>
-				` : html`
-					${element.isTransfer ? html`
-						<p class="transfer">${t('transferinfo', [parseName(element.arrival.point), element.distance])}</p>
-					` : html`
-						<table>
-							<thead>
-								<tr>
-									<td colspan="4">${element.line.name} ${element.line.additionalName ? '('+element.line.additionalName+')' : ''} → ${element.direction} ${element.cancelled ? html`<b style="color:red;">${t('cancelled-ride')}</b>` : ''}</td>
-								</tr>
-								<tr>
-									<th>${t('arrival')}</th>
-									<th>${t('departure')}</th>
-									<th>${t('station')}</th>
-									<th>${t('platform')}</th>
-								</tr>
-							</thead>
-							<tbody>
-								${element.stopovers.map(stop => html`
-									<tr class="stop ${stop.cancelled ? 'cancelled' : ''}" @click=${() => {location.href = "https://marudor.de/"+stop.stop.id+"?searchType=hafas"}}>
-										<td>${timeTemplate(stop.arrival)}</td>
-										<td>${timeTemplate(stop.departure)}</td>
-										<td>${stop.stop.name} ${ds100Names(stop.stop.id)}</td>
-										<td>${stopPlatformTemplate(stop)}</td>
-									</tr>
-								`)}
-								${(element.remarks || []).map(element => html`
-									<tr><td colspan="4"><smal>${element.text}</small></td></tr>
-								`)}
-							</tbody>
-						</table>
-					`}
-				`}
-			`)}
+	return html`
+		<div id="journeyView">
+			<div id="header">
+				<a class="back" href="#/${requestId}"></a>
+				<p>
+					<h2>
+						<span id="fromName2">${parseName(departure.point)}</span>
+						<span> - </span>
+						<span id="toName2">${parseName(arrival.point)}</span>
+					</h2>
+				</p>
+				<p>
+					<b>
+						<span>${t('duration')}: </span>
+						<span id="duration">${formatDuration(duration)}</span>
+						<span> | ${t('changes')}: </span>
+						<span id="changes">${changes-1}</span>
+						<span> | ${t('date')}: </span>
+						<span id="date2">${parseDateTime(departure.plannedTime, 'date')}</span>
+					</b>
+				</p>
+				<div class="reload" id="reload-journey" @click=${() => reloadJourney(requestId, journeyId)}></div>
+			</div>
+	
+			<div id="connection">
+				${data.legs.map(legTemplate)}
+			</div>
 		</div>
-	</div>
-`};
+	`;
+};
 
 const timeTemplate = (data, mode) => {
 	let delay = 0;
diff --git a/client/js/journeysView.js b/client/js/journeysView.js
@@ -53,7 +53,7 @@ const journeyOverviewTemplate = (data, key) => {
 
 	let departureTime = departure.prognosedTime ? departure.prognosedTime : departure.plannedTime;
 	let arrivalTime   = arrival.prognosedTime   ? arrival.prognosedTime   : arrival.plannedTime;
-	let duration      = (arrivalTime - departureTime)/60;
+	let duration      = arrivalTime - departureTime;
 
 	for (let legKey in data.journeys[key].legs) {
 		let leg = data.journeys[key].legs[legKey];

@@ -70,7 +70,7 @@ const journeyOverviewTemplate = (data, key) => {
 	<tr class="connection ${cancelled ? 'cancelled' : ''}" @click=${() => go('/'+data.reqId + '/' + key)}">
 		<td>${timeTemplate(departure, 'departure')}</td>
 		<td>${timeTemplate(arrival, 'arrival')}</td>
-		<td title="${changesDuration > 0 ? 'Davon '+convertMinsToHrsMins(changesDuration)+' Umstiegsdauer' : ''}">${convertMinsToHrsMins(duration)}</td>
+		<td title="${changesDuration > 0 ? 'Davon '+formatDuration(changesDuration)+' Umstiegsdauer' : ''}">${formatDuration(duration)}</td>
 		<td>${changes-1}</td>
 		<td>${products.join(', ')}</td>
 	</tr>`;