owlboard-svelte/src/lib/ldb/staff/table/table-generator.svelte

321 lines
8.6 KiB
Svelte

<script lang="ts">
import Reason from "$lib/raw-fetchers/reason.svelte";
import { tocs as tocMap } from "$lib/stores/tocMap";
import type { TrainServices, ServiceLocation } from "@owlboard/ts-types";
import { fade } from "svelte/transition";
export let services: TrainServices[];
export let click: Function;
function detail(event: any, rid: string, uid: string, tid: string) {
const target = event.target;
click(rid, uid, tid);
}
async function formatLocations(locations: ServiceLocation[]): Promise<string> {
let tiplocs: string[] = [];
for (const location of locations) {
tiplocs.push(location.tiploc);
}
return tiplocs.join(" & ");
}
async function classGenerator(service: TrainServices) {
// This function needs updating next
let otherArr: string[] = [];
let arrArr: string[] = [];
let depArr: string[] = [];
let platArr: string[] = [];
if (service.isCancelled) {
otherArr.push("canc");
}
if (service.serviceIsSupressed) {
otherArr.push("nonPass");
}
if (service.platformIsHidden) {
platArr.push("nonPass");
}
function checkLateEarly(originalTime: Date | undefined, comparedTime: Date | undefined, arr: string[]) {
if (originalTime !== undefined && comparedTime instanceof Date) {
if (originalTime < comparedTime) {
arr.push("late");
} else if (originalTime > comparedTime) {
arr.push("early");
}
}
}
checkLateEarly(service.sta, service.eta, arrArr);
checkLateEarly(service.sta, service.ata, arrArr);
checkLateEarly(service.std, service.etd, depArr);
checkLateEarly(service.std, service.atd, depArr);
return {
other: otherArr.join(" "),
arr: arrArr.join(" "),
dep: depArr.join(" "),
plat: platArr.join(" "),
};
}
function fmtTime(date: Date | string | undefined): string | false {
if (typeof date === "string") return date;
if (date instanceof Date) {
const hours = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
return `${hours}:${minutes}`;
} else {
return false;
}
}
</script>
<p class="smallScreen">Your display is too small to view this data</p>
<p class="smallScreen">Try rotating your device</p>
<table in:fade={{duration:500}}>
<tr>
<th class="id">ID</th>
<th class="from">From</th>
<th class="to">To</th>
<th class="plat">Plat</th>
<th class="time arrsch">Sch</th>
<th class="time arrexp">Exp</th>
<th class="time depsch">Sch</th>
<th class="time depexp">Exp</th>
</tr>
<tr>
<th class="other" colspan="4" />
<th class="timepair" colspan="2">Arrival</th>
<th class="timepair" colspan="2">Departure</th>
</tr>
{#each services as service}
<tr
class="dataRow"
on:click={(event) => detail(event, service.rid, service.uid, service.trainid)}
on:keypress={(event) => detail(event, service.rid, service.uid, service.trainid)}
>
{#await classGenerator(service) then classes}
<!-- HEADCODE -->
<td class="id">{service.trainid}</td>
<!-- ORIGIN -->
<td class="loc from {classes.other}">{#await formatLocations(service.origin) then origin}{origin}{/await}</td>
<!-- DESTINATION -->
<td class="loc to {classes.other}">{#await formatLocations(service.destination) then dest}<span class="locName">{dest}</span>{/await}</td>
<!-- PLATFORM -->
<td class="plat {classes.other} {classes.plat}">{service.platform || "-"}</td>
<!-- SCHEDULED ARR -->
<td class="time schTime {classes.other}">{fmtTime(service?.sta) || "-"}</td>
<!-- EXPECTED/ACTUAL ARR -->
<td class="time {classes.other} {classes.arr}">{fmtTime(service.eta) || fmtTime(service.ata) || "-"}</td>
<!-- SCHEDULED DEP -->
<td class="time schTime {classes.other}">{fmtTime(service.std) || "-"}</td>
<!-- EXPECTED/ACTUAL DEP -->
<td class="time {classes.other} {classes.dep}">{fmtTime(service.etd) || fmtTime(service.atd) || "-"}</td>
{/await}
</tr>
<tr>
<td colspan="1" />
<td class="tableTxt" colspan="7">
{#if service.destination?.[0] && service.destination[0].via}<span class="via">{service.destination[0].via}</span><br />{/if}
{tocMap.get(service.operatorCode.toLowerCase()) || service.operatorCode}
{#if service.length} | {service.length} carriages{/if}
{#if service.delayReason}
<br />
<span class="delayTxt">
<Reason type={"delay"} code={service.delayReason} />
</span>
{/if}
{#if service.cancelReason}
<br />
<span class="cancTxt">
<Reason type={"cancel"} code={service.cancelReason} />
</span>
{/if}
</td>
</tr>
{/each}
</table>
<style>
table {
table-layout: fixed;
width: 100%;
max-width: 875px;
margin: auto;
padding: 0px;
color: white;
}
th {
font-size: 12px;
margin: 0px;
}
.dataRow {
font-family: ubuntu, monospace;
vertical-align: top;
cursor: pointer;
font-size: 16px;
line-height: 1;
padding: 0;
margin: 0;
}
/* Table Columns */
.id {
width: 8%;
}
.from {
width: 14%;
}
.to {
width: 14%;
}
.plat {
width: 6%;
}
.time {
width: 9%;
}
td.id {
color: lightblue;
text-align: left;
padding-left: 2px;
}
td.from,
td.to {
color: yellow;
}
td.to {
text-align: right;
}
td.from,
th.from {
text-align: left;
}
td.time {
font-size: 15px;
vertical-align: top;
}
.tableTxt {
text-align: left;
padding-left: 2px;
color: var(--secondary-text-color);
vertical-align: top;
font-size: 12px;
padding-bottom: 10px;
}
.delayTxt {
color: var(--main-warning-color);
}
.cancTxt {
color: var(--main-alert-color);
}
.via {
color: yellow;
padding-left: 0px;
}
/* Handle small screens */
.smallScreen {
display: none;
margin: 20px;
}
@media screen and (max-width: 335px) {
th {
font-size: 10px;
}
.dataRow {
font-size: 12px;
}
td.time {
font-size: 12px;
}
.tableTxt {
font-size: 10px;
}
}
@media screen and (max-width: 279px) {
table {
display: none;
}
.smallScreen {
display: block;
}
}
/* Handle Large Screens */
@media screen and (min-width: 375px) {
.dataRow {
font-size: 18px;
}
td.time {
font-size: 16px;
}
}
@media screen and (min-width: 450px) {
.dataRow {
font-size: 20px;
}
td.time {
font-size: 19px;
}
.tableTxt {
font-size: 14px;
}
td.to,
td.from,
th.to,
th.from {
text-align: left;
}
}
/* Conditional Classes */
.loc.canc,
.canc {
color: grey;
text-decoration: line-through;
opacity: 0.8;
}
.nonPass {
opacity: 0.4;
}
.late {
animation: pulse-late 1.5s linear infinite;
}
.canc.time {
animation: pulse-cancel 1.5s linear infinite;
}
.early {
animation: pulse-early 1.5s linear infinite;
}
/* Animation Definitions */
@keyframes pulse-late {
50% {
color: var(--main-warning-color);
}
}
@keyframes pulse-cancel {
50% {
color: var(--main-alert-color);
}
}
@keyframes pulse-early {
50% {
color: rgb(136, 164, 255);
}
}
</style>