From 086da49c678739257989ec9540b370bcc21f8248 Mon Sep 17 00:00:00 2001 From: Romein van Buren Date: Thu, 23 Feb 2023 14:47:51 +0100 Subject: [PATCH] Concept refactoring; accept tiles and props from other plugins through hooks. --- gui/dashboard/app.css | 2 + gui/dashboard/app.svelte | 140 +++++++++++++++++------------ gui/dashboard/tile-rawvalue.svelte | 24 ----- gui/dashboard/tile.svelte | 79 +++++++++++----- index.js | 42 ++++----- 5 files changed, 160 insertions(+), 127 deletions(-) delete mode 100644 gui/dashboard/tile-rawvalue.svelte diff --git a/gui/dashboard/app.css b/gui/dashboard/app.css index 5771a1f..53b5d71 100644 --- a/gui/dashboard/app.css +++ b/gui/dashboard/app.css @@ -5,6 +5,7 @@ html, body { --grey: grey; --red: #f00; --green: #1d641d; + --orange: #bf5900; --dark: #0a0a0a; --radius: 10px; --cols: 4; @@ -22,6 +23,7 @@ html, body { --tile-bg: #dedede; --dark: #c2c2c2; --green: #377137; + --orange: #bf5900; } .mb { diff --git a/gui/dashboard/app.svelte b/gui/dashboard/app.svelte index d4e1bb6..d37e729 100644 --- a/gui/dashboard/app.svelte +++ b/gui/dashboard/app.svelte @@ -1,92 +1,114 @@ + +
- {#each tiles as tile (tile.id)} + {#each tilesOnPage || [] as tile (tile.serviceId)}
Math.sqrt(d) * 120) : 0 }} > - +
{/each}
diff --git a/gui/dashboard/tile-rawvalue.svelte b/gui/dashboard/tile-rawvalue.svelte deleted file mode 100644 index 9a435f7..0000000 --- a/gui/dashboard/tile-rawvalue.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - - -
- {value} -
-
- - diff --git a/gui/dashboard/tile.svelte b/gui/dashboard/tile.svelte index b64608a..1c697a2 100644 --- a/gui/dashboard/tile.svelte +++ b/gui/dashboard/tile.svelte @@ -2,25 +2,21 @@ import { formatDuration } from './lib'; import { onMount } from 'svelte'; - export let title; - export let subtitle; - export let color; - export let date; - export let since; + export let tile; let formattedDuration = ''; - $: formattedDate = date ? date.toLocaleTimeString('en-GB', { + $: formattedDate = tile.service?.checked ? tile.service.checked.toLocaleTimeString('en-GB', { timeStyle: 'short', }) : ''; onMount(() => { function updateDuration() { formattedDuration = formatDuration( - new Date().getTime() - since.getTime() + new Date().getTime() - tile.since.getTime() ); } - if (since) { + if (tile.since) { updateDuration(); const interval = setInterval(updateDuration, 100); return () => clearInterval(interval); @@ -28,22 +24,33 @@ }); -
- {#if title || subtitle} -
- {#if title} -
{title}
- {/if} +
+
+ {#if tile.service?.name?.en} +
{tile.service.name.en}
+ {/if} - {#if subtitle} -
{subtitle}
- {/if} -
- {/if} + {#if tile.service?.cluster} +
{tile.service.cluster}
+ {/if} + + {#if tile.badges?.length} +
+ {#each tile.badges as badge} + {badge} + {/each} +
+ {/if} +
-
- {#if date || since} +
+
+ {tile.statusText} +
+
+ + {#if tile.date || tile.since}
{#if formattedDate}
{formattedDate}
{/if} {#if formattedDuration}
{formattedDuration}
{/if} @@ -62,19 +69,25 @@ flex-direction: column; } - .tile.red { + .tile.prio2 { background-color: var(--red); border-color: var(--red); color: #fff; } - .tile.green { + .tile.prio1 { + background-color: var(--orange); + border-color: var(--orange); + color: #fff; + } + + .tile.prio0 { border-color: var(--green); background-color: var(--green); color: #fff; } - .tile.grey { + .tile.prio-1 { opacity: 0.5; border-color: var(--grey); } @@ -98,6 +111,18 @@ opacity: 0.7; } + .badges { + margin-top: 0.2em; + } + .badges .badge { + display: inline-block; + margin-right: 0.3em; + background-color: rgba(0, 0, 0, 0.3); + border: 1px solid rgba(0, 0, 0, 0.4); + padding: 0.2em 0.4em; + border-radius: 0.4em; + } + .bottom { display: flex; margin-top: auto; @@ -117,4 +142,10 @@ flex-grow: 1; display: flex; } + + .statustext { + font-size: 3em; + font-weight: 600; + margin-top: auto; + } diff --git a/index.js b/index.js index 27295b2..c0af867 100644 --- a/index.js +++ b/index.js @@ -375,32 +375,38 @@ module.exports = { .sort({ date: -1 }) .toArray(); - const servicesUp = []; - const servicesDown = []; - const servicesUnknown = []; + const tiles = []; downIdsAfter = []; for (let service of services) { const beat = heartbeats.find(b => b.webservice === service.id); service = mapService(service, beat); + const tile = { + service: service, + serviceId: service.id, + badges: [], + prio: -1, + }; if (!beat) { - servicesUnknown.push(service); + tile.prio = -1; // no data (grey) + tile.statusText = 'no data'; } else if (beat.down) { - servicesDown.push(service); - downIdsAfter.push(service.id); + tile.prio = 2; // down (red) + tile.statusText = 'down'; + downIdsAfter.push(tile.serviceId); } else { - servicesUp.push(service); + tile.prio = 0; // ok (green) + tile.statusText = 'ok'; } + + tiles.push(tile); } - const total = [ - ...servicesUp, - ...servicesDown, - ...servicesUnknown, - ].length; + // Let other plugins enrich dashboard tiles with custom badges and priorities. + await server.executePostHooks('pupulateDashboardTiles', { tiles }); let newOutage = false; for (const id of downIdsAfter) { @@ -408,20 +414,14 @@ module.exports = { newOutage = true; } } - downIdsBefore = JSON.parse(JSON.stringify(downIdsAfter)); + downIdsBefore = [ ...downIdsAfter ]; try { if (newOutage) { ws.send(JSON.stringify({ cmd: 'bell' })); } - ws.send(JSON.stringify({ - cmd: 'data', - servicesUp, - servicesDown, - servicesUnknown, - total, - })); + ws.send(JSON.stringify({ cmd: 'data', tiles: tiles })); } catch { return; @@ -804,7 +804,7 @@ module.exports = { method: 'get', handler: async (req, res) => { // const cacheValid = !!renderedDashboard; - const cacheValid = true; + const cacheValid = false; if (!cacheValid) { // Build dashboard let cssOutput = '';