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

View File

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

View File

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

View File

@ -3,6 +3,7 @@
import { tocs as tocMap } from "$lib/stores/tocMap"; import { tocs as tocMap } from "$lib/stores/tocMap";
import type { TrainServices, ServiceLocation } from "@owlboard/ts-types"; import type { TrainServices, ServiceLocation } from "@owlboard/ts-types";
import { fade } from "svelte/transition";
export let services: TrainServices[]; export let services: TrainServices[];
export let click: Function; export let click: Function;
@ -74,7 +75,7 @@
<p class="smallScreen">Your display is too small to view this data</p> <p class="smallScreen">Your display is too small to view this data</p>
<p class="smallScreen">Try rotating your device</p> <p class="smallScreen">Try rotating your device</p>
<table> <table in:fade={{duration:500}}>
<tr> <tr>
<th class="id">ID</th> <th class="id">ID</th>
<th class="from">From</th> <th class="from">From</th>

View File

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

View File

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