From 9d45ab32463cfcc50f464d0c9384266c1f97710a Mon Sep 17 00:00:00 2001 From: Gabriel Engel Date: Wed, 23 Nov 2022 07:52:59 -0300 Subject: [PATCH] New Badges components: destination, public, status, teams + container/status --- apps/ui/src/lib/common.ts | 4 +- .../components/badges/DestinationBadge.svelte | 15 ++++ .../lib/components/badges/PublicBadge.svelte | 19 +++++ .../lib/components/badges/StatusBadge.svelte | 25 +++++++ .../lib/components/badges/TeamsBadge.svelte | 17 +++++ apps/ui/src/lib/container/status.ts | 73 +++++++++++++++++++ 6 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 apps/ui/src/lib/components/badges/DestinationBadge.svelte create mode 100644 apps/ui/src/lib/components/badges/PublicBadge.svelte create mode 100644 apps/ui/src/lib/components/badges/StatusBadge.svelte create mode 100644 apps/ui/src/lib/components/badges/TeamsBadge.svelte create mode 100644 apps/ui/src/lib/container/status.ts diff --git a/apps/ui/src/lib/common.ts b/apps/ui/src/lib/common.ts index c67a88929..9ed667f43 100644 --- a/apps/ui/src/lib/common.ts +++ b/apps/ui/src/lib/common.ts @@ -3,6 +3,8 @@ import { addToast } from '$lib/store'; export const asyncSleep = (delay: number) => new Promise((resolve) => setTimeout(resolve, delay)); +export let initials = (str:string) => (str||'').split(' ').map( (wrd) => wrd[0]).join('') + export function errorNotification(error: any | { message: string }): void { if (error.message) { if (error.message === 'Cannot read properties of undefined (reading \'postMessage\')') { @@ -87,4 +89,4 @@ export function handlerNotFoundLoad(error: any, url: URL) { export function getRndInteger(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1)) + min; -} \ No newline at end of file +} diff --git a/apps/ui/src/lib/components/badges/DestinationBadge.svelte b/apps/ui/src/lib/components/badges/DestinationBadge.svelte new file mode 100644 index 000000000..e9f3fe7ed --- /dev/null +++ b/apps/ui/src/lib/components/badges/DestinationBadge.svelte @@ -0,0 +1,15 @@ + + +{#if (name||'').length > 0} + + {initials(name)} + + {name} +{/if} \ No newline at end of file diff --git a/apps/ui/src/lib/components/badges/PublicBadge.svelte b/apps/ui/src/lib/components/badges/PublicBadge.svelte new file mode 100644 index 000000000..7ce01a074 --- /dev/null +++ b/apps/ui/src/lib/components/badges/PublicBadge.svelte @@ -0,0 +1,19 @@ +
+ + + + + + + + +
\ No newline at end of file diff --git a/apps/ui/src/lib/components/badges/StatusBadge.svelte b/apps/ui/src/lib/components/badges/StatusBadge.svelte new file mode 100644 index 000000000..9b386a859 --- /dev/null +++ b/apps/ui/src/lib/components/badges/StatusBadge.svelte @@ -0,0 +1,25 @@ + +{#await getting} + ... +{:then status} + + {status} + +{/await} diff --git a/apps/ui/src/lib/components/badges/TeamsBadge.svelte b/apps/ui/src/lib/components/badges/TeamsBadge.svelte new file mode 100644 index 000000000..a02078f3e --- /dev/null +++ b/apps/ui/src/lib/components/badges/TeamsBadge.svelte @@ -0,0 +1,17 @@ + + + + 🏢 + {#each teams as team} + + {initials(team.name)} + + {team.name} + {/each} + \ No newline at end of file diff --git a/apps/ui/src/lib/container/status.ts b/apps/ui/src/lib/container/status.ts new file mode 100644 index 000000000..f520554a0 --- /dev/null +++ b/apps/ui/src/lib/container/status.ts @@ -0,0 +1,73 @@ +// +// Maps Container ID x Operation Status +// +// Example response of $status => {'123asdf': 'degraded', '124asdf': 'running'} + +import { writable, get as getStore } from 'svelte/store'; +import { get } from '$lib/api'; + +export let containerStatus = writable({}); + +let PERMITED_STATUS = ['loading', 'running', 'healthy', 'building', 'degraded', 'stopped', 'error']; + +// refreshStatus([{id}]) +export async function refreshStatus(list:Array) { + for (const item of list) { + setStatus(item.id, 'loading'); + getStatus(item, true); + } +} + +export async function getStatus(resource: any, force: boolean = false) { + const { id, buildPack, dualCerts, engine } = resource; + let newStatus = 'stopped'; + + // Already set and we're not forcing + if (getStore(containerStatus)[id] && !force) return getStore(containerStatus)[id]; + + try { + if (buildPack) { // Application + const response = await get(`/applications/${id}/status`); + newStatus = parseApplicationsResponse(response); + } else if (typeof dualCerts !== 'undefined') { // Service + const response = await get(`/services/${id}/status`); + newStatus = parseServiceResponse(response); + } else if (typeof engine !== 'undefined'){ // Destination/Server + const response = await get(`/destinations/${id}/status`); + newStatus = response.isRunning ? 'running' : 'stopped'; + } else { // Database + const response = await get(`/databases/${id}/status`); + newStatus = response.isRunning ? 'running' : 'stopped'; + } + } catch (error) { + newStatus = 'error'; + } + + setStatus(id, newStatus); + // console.log("GOT:", id, newStatus) + return newStatus +} + +const setStatus = (thingId, newStatus) => { + if(!PERMITED_STATUS.includes(newStatus)) + throw(`Change to ${newStatus} is not permitted. Try: ${PERMITED_STATUS.join(', ')}`); + containerStatus.update(n => Object.assign(n, {thingId: newStatus})); +}; + +// -- Response Parsing + +function parseApplicationsResponse(list:Array){ + if (list.length === 0) return 'stopped'; + if (list.length === 1) return list[0].status.isRunning ? 'running' : 'stopped'; + return allWorking(list.map( (el:any) => el.status.isRunning )) +} + +function parseServiceResponse(response:any){ + if (Object.keys(response).length === 0) return 'stopped'; + let list = Object.keys(response).map((el) => el.status.isRunning) + return allWorking(list) ? 'running' : 'degraded' +} + +function allWorking(list:Array){ + return list.reduce((acum:boolean,res:boolean) => acum && res) ? 'running' : 'degraded'; +}