Implement time bar and update LDB components to handle it

This commit is contained in:
Fred Boniface 2024-07-12 15:04:06 +01:00
parent 7f1dc1ac3f
commit 6d175f300f
6 changed files with 64 additions and 59 deletions

View File

@ -1,5 +1,6 @@
<script>
import { fly } from "svelte/transition";
import { IconAlertCircle } from "@tabler/icons-svelte";
import { fly } from "svelte/transition";
export let alerts = [];
$: uniqueAlerts = [...new Set(alerts)];
@ -10,7 +11,7 @@
displayAlerts = !displayAlerts;
}
function numberAsWord(number) {
function numberAsWord(number = 0) {
const words = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
let word = words[number];
if (word) {
@ -20,17 +21,14 @@
}
</script>
<div id="block"><!--Prevent content slipping underneath the bar--></div>
<div id="bar" on:click={alertsToggle} on:keypress={alertsToggle}>
<img src="/images/navigation/alert.svg" alt="" />
<span class="image"><IconAlertCircle /></span>
{#if uniqueAlerts.length == 1}
<p id="bartext">There is one active alert</p>
{:else if uniqueAlerts.length > 1}
{:else}
<p id="bartext">
There are {numberAsWord(uniqueAlerts.length)} active alerts
</p>
{:else}
<p id="bartext">There are no active alerts</p>
{/if}
<p id="arrow" class:displayAlerts>V</p>
</div>
@ -43,46 +41,35 @@
{/if}
<style>
#block {
height: 40px;
}
#bar {
position: relative;
margin-top: 0;
padding: 0;
width: 100%;
height: 40px;
background-color: var(--main-alert-color);
opacity: 1;
position: fixed;
width: 100%;
top: 50px;
left: 0px;
z-index: 10;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 2;
}
img {
height: 25px;
width: 25px;
position: absolute;
left: 8px;
top: 8px;
margin: 0;
padding: 0;
.image {
margin-left: 15px;
margin-top: 4px;
}
#bartext {
color: white;
margin: auto;
font-weight: 600;
margin-top: 8px;
margin-bottom: 0px;
padding: 0px;
margin: 0 0 0 0;
padding: 0;
}
#arrow {
color: white;
font-family: Arial, Helvetica, sans-serif;
font-weight: 900;
position: absolute;
margin-top: 0;
right: 15px;
top: 11px;
border: none;
margin-right: 15px;
background-color: transparent;
transition-duration: 500ms;
transition-delay: 00ms;
@ -91,7 +78,7 @@
background-color: transparent;
}
#alerts {
position: fixed;
position: absolute;
background-color: var(--main-alert-color);
opacity: 0.9;
width: 100%;
@ -100,6 +87,7 @@
overflow-x: clip;
left: 0;
top: 89px;
z-index: 1;
}
.alert {
color: white;

View File

@ -4,9 +4,10 @@
import { onMount } from "svelte";
import Loading from "$lib/navigation/loading.svelte";
import OverlayIsland from "$lib/islands/overlay-island.svelte";
import AlertBar from "$lib/ldb/nrcc/alert-bar.svelte";
import AlertBar from "$lib/ldb/common/nrcc/alert-bar.svelte";
import Island from "$lib/islands/island.svelte";
import { getApiUrl } from "$lib/scripts/upstream";
import TimeBar from "$lib/navigation/TimeBar.svelte";
let requestedStation;
$: requestedStation = station;
@ -151,6 +152,8 @@
<AlertBar {alerts} />
{/if}
<TimeBar updatedTime={dataAge} />
{#if isLoading}
<Loading />
{:else if dataAge}

View File

@ -5,8 +5,9 @@
import { detailInit, defineDetail } from "./train-detail";
import TrainDetail from "./train-detail.svelte";
import { fetchStaffLdb } from "./fetch";
import AlertBar from "../nrcc/alert-bar.svelte";
import AlertBar from "../common/nrcc/alert-bar.svelte";
import TimeBar from "$lib/navigation/TimeBar.svelte";
import { onMount } from "svelte";
export let station: string;
export let title: string | undefined = "Loading...";
@ -27,7 +28,10 @@
console.log(`Station: ${station}`);
let updatedTime: Date;
async function callFetch(station: string): Promise<StaffLdb> {
console.log("callFetch function called")
const data = await fetchStaffLdb(station);
if (data.data) {
title = data.data.locationName;
@ -35,6 +39,10 @@
for (const msg of data.data.nrccMessages) {
nrcc.push(msg.xhtmlMessage);
}
nrcc = nrcc; // Reassign to ensure Svelte reloads
}
if (data.data.generatedAt) {
updatedTime = new Date(data.data.generatedAt);
}
return data.data;
}
@ -43,13 +51,18 @@
throw new Error("Unable to Fetch Data");
}
// Add additional margin if AlertBox is displayed
let generatedMarginTop = "10px";
$: if (nrcc.length) {
generatedMarginTop = "50px";
}
onMount(async () => {
console.log("staff-ldb component mounted");
})
</script>
{#if nrcc.length}
<AlertBar alerts={nrcc} />
{/if}
<TimeBar bind:updatedTime />
{#key detail}
{#if detail.show}
<TrainDetail {detail} close={hideDetail} />
@ -57,15 +70,10 @@
{/key}
{#await callFetch(station)}
<TimeBar updatedTime={undefined} />
<Loading />
{:then data}
{#if data}
{#if nrcc.length}
<AlertBar alerts={nrcc} />
{/if}
<TimeBar updatedTime={new Date(data.generatedAt)} />
<p class="generatedTime" style="margin-top: {generatedMarginTop};">Updated: {new Date(data.generatedAt).toLocaleTimeString()}</p>
{#if data.trainServices?.length}
<TableGenerator services={data.trainServices} click={showDetail} />
{/if}
@ -81,7 +89,6 @@
{/if}
{/if}
{:catch}
<TimeBar updatedTime={new Date} />
<h2>Error</h2>
<p>ERR-CODE: {errorDetail.code}</p>
<p>Message:<br />{errorDetail.message}</p>

View File

@ -3,6 +3,7 @@
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;
@ -74,7 +75,7 @@
<p class="smallScreen">Your display is too small to view this data</p>
<p class="smallScreen">Try rotating your device</p>
<table>
<table in:fade={{duration:500}}>
<tr>
<th class="id">ID</th>
<th class="from">From</th>

View File

@ -1,9 +1,11 @@
<script lang="ts">
import { onMount } from "svelte";
import { fade } from "svelte/transition";
export let updatedTime: Date | undefined;
let currentTime: string = "00:00:00"
let updateDisplay: string;
function updateTime() {
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
@ -13,15 +15,16 @@ function updateTime() {
}
onMount(() => {
console.log("TimeBar component mounted")
updateTime();
const interval = setInterval(updateTime, 500);
const interval = setInterval(updateTime, 250);
return () => clearInterval(interval);
})
</script>
<div id="TimeBar">
{#if updatedTime}
<span class="updated-time">Updated: {updatedTime.toLocaleTimeString()}</span>
<span in:fade class="updated-time">Updated: {updatedTime.toLocaleTimeString()}</span>
{:else}
<span></span>
{/if}

View File

@ -1,4 +1,4 @@
<script>
<script lang="ts">
import Header from "$lib/navigation/header.svelte";
import Nav from "$lib/navigation/nav-ldb.svelte";
import PublicLdb from "$lib/ldb/public-ldb.svelte";
@ -12,9 +12,10 @@
return new URLSearchParams(window.location.search).get("station");
}
let station = "";
let staff = false;
let uuidValue = "";
let station: string;
let staff: boolean;
let uuidValue: string;
let blockLoading: boolean = true;
$: uuidValue = $uuid;
@ -26,17 +27,19 @@
} else {
title = "Public Board";
}
blockLoading = false;
});
</script>
<Header {title} />
<!-- If 'uuid' exists in store then load StaffLdb else load PublicLdb -->
{#if !staff}
<PublicLdb {station} bind:title />
{:else}
<StaffLdb {station} bind:title />
<!--<StaffLdb {station} bind:title={title} /> -- Temporary, Disable StaffLdb - it isn't implemented -->
{#if !blockLoading}
{#if !staff}
<PublicLdb {station} bind:title />
{:else}
<StaffLdb {station} bind:title />
{/if}
{/if}
<Nav />