Dashboard: server-side data processing

Signed-off-by: Romein van Buren <romein@vburen.nl>
This commit is contained in:
Romein van Buren 2022-07-12 09:40:49 +02:00
parent 87b583e0dd
commit 25cb7652e1
Signed by: romein
GPG Key ID: 0EFF8478ADDF6C49
5 changed files with 92 additions and 49 deletions

View File

@ -2,11 +2,16 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import TileRawValue from './tile-rawvalue.svelte'; import TileRawValue from './tile-rawvalue.svelte';
import Settings from './settings.svelte'; import Settings from './settings.svelte';
//import { flip } from 'svelte/animate';
//import { shuffle } from './lib';
//const [ send, receive ] = shuffle;
const size = 3 * 4; const size = 3 * 4;
let lastUpdated = new Date(); let lastUpdated = new Date();
let lastUpdatedFormatted = ''; let lastUpdatedFormatted = '';
let services = []; let servicesUp = [];
let servicesDown = [];
let servicesUnknown = [];
let pageNum = -1; let pageNum = -1;
function tileProps(service) { function tileProps(service) {
@ -21,7 +26,7 @@
props.color = 'grey'; props.color = 'grey';
props.sort = 20; props.sort = 20;
} }
if (service.lastBeat.down) { else if (service.lastBeat.down) {
props.value = 'down'; props.value = 'down';
props.color = 'red'; props.color = 'red';
props.sort = 0; props.sort = 0;
@ -50,24 +55,7 @@
break; break;
case 'data': case 'data':
const tempServices = []; ({ servicesUp, servicesDown, servicesUnknown } = data);
const d = data.data;
const ids = Object.keys(d);
ids.sort((a, b) => tileProps(d[a]).sort - tileProps(d[b]).sort);
if ((ids.length > size) || (pageNum === -1)) {
pageNum++;
}
if (pageNum * size >= ids.length) {
pageNum = 0;
}
for (let i = pageNum * size; (i < ids.length) && (i < size + size * pageNum); i++) {
tempServices.push(d[ids[i]]);
}
services = tempServices;
break; break;
default: default:
@ -84,9 +72,25 @@
<div class="tiles"> <div class="tiles">
<TileRawValue title="Last updated" value={lastUpdatedFormatted} /> <TileRawValue title="Last updated" value={lastUpdatedFormatted} />
{#each services as service} {#each servicesDown as service (service.id)}
<TileRawValue {...tileProps(service)} /> <TileRawValue {...tileProps(service)} />
{/each} {/each}
{#each servicesUp as service (service.id)}
<TileRawValue {...tileProps(service)} />
{/each}
{#each servicesUnknown as service (service.id)}
<TileRawValue {...tileProps(service)} />
{/each}
<!--{#each services as service (service.id)}
<div
in:receive={{ key: service.id }}
out:send={{ key: service.id }}
animate:flip
>
<TileRawValue {...tileProps(service)} />
</div>
{/each}-->
</div> </div>
</div> </div>
</div> </div>

38
gui/dashboard/lib.js Normal file
View File

@ -0,0 +1,38 @@
import { get, writable } from 'svelte/store';
//import { quintOut } from 'svelte/easing';
//import { crossfade } from 'svelte/transition';
function createSettingsStore() {
const s = writable(0);
function updateStorage(val) {
window.localStorage.setItem('statusdash', JSON.stringify(val));
s.set(val);
}
return {
subscribe: s.subscribe,
set: val => updateStorage(val),
update: val => updateStorage({ ...get(s), val }),
};
}
export const settings = createSettingsStore();
/*
export const shuffle = crossfade({
fallback(node) {
const style = getComputedStyle(node);
const transform = style.transform === 'none' ? '' : style.transform;
return {
duration: 600,
easing: quintOut,
css: t => `
transform: ${transform} scale(${t});
opacity: ${t}
`,
};
},
});
*/

View File

@ -1,6 +1,6 @@
<script> <script>
import Modal from './modal.svelte'; import Modal from './modal.svelte';
import { settings } from './stores'; import { settings } from './lib';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { get } from 'svelte/store'; import { get } from 'svelte/store';

View File

@ -1,18 +0,0 @@
import { get, writable } from 'svelte/store';
function createSettingsStore() {
const s = writable(0);
function updateStorage(val) {
window.localStorage.setItem('statusdash', JSON.stringify(val));
s.set(val);
}
return {
subscribe: s.subscribe,
set: val => updateStorage(val),
update: val => updateStorage({ ...get(s), val }),
};
}
export const settings = createSettingsStore();

View File

@ -5,6 +5,13 @@ const { makeId } = require('core/makeid');
const decoder = new TextDecoder('utf-8'); const decoder = new TextDecoder('utf-8');
let uws; let uws;
const mapService = (s, beat) => ({
id: s.id,
name: s.name,
cluster: s.cluster,
lastBeat: beat,
});
async function createDashboardSocket(server) { async function createDashboardSocket(server) {
uws = server.ws({ uws = server.ws({
route: '/statusdashboard/socket', route: '/statusdashboard/socket',
@ -34,21 +41,33 @@ async function createDashboardSocket(server) {
.find({ webservice: { $in: services.map(s => s.id) } }) .find({ webservice: { $in: services.map(s => s.id) } })
.sort({ date: -1 }) .sort({ date: -1 })
.toArray(); .toArray();
const mappedServices = {};
for (const s of services) { const servicesUp = [];
const lastBeat = heartbeats.find(h => h.webservice === s.id); const servicesDown = [];
mappedServices[s.id] = { const servicesUnknown = [];
name: s.name, console.log(heartbeats);
lastBeat: lastBeat || {},
cluster: s.cluster, for (let service of services) {
}; const beat = heartbeats.find(b => b.webservice === service.id);
service = mapService(service, beat);
if (!beat) {
servicesUnknown.push(service);
}
else if (beat.down) {
servicesDown.push(service);
}
else {
servicesUp.push(service);
}
} }
try { try {
ws.send(JSON.stringify({ ws.send(JSON.stringify({
cmd: 'data', cmd: 'data',
data: mappedServices, servicesUp,
servicesDown,
servicesUnknown,
})); }));
} }
catch { catch {