diff --git a/svelte/src/admin_panel/PeerTable.svelte b/svelte/src/admin_panel/PeerTable.svelte index 973ae1a..454e2b2 100644 --- a/svelte/src/admin_panel/PeerTable.svelte +++ b/svelte/src/admin_panel/PeerTable.svelte @@ -2,6 +2,8 @@ import { flip } from "svelte/animate"; import { formatDataVolume } from "util/Formatting"; import SortButton from "layout/SortButton.svelte"; +import { loading_run } from "lib/Loading"; +import { admin_decommission_node } from "lib/AdminAPI"; let { peers = $bindable([]) @@ -33,6 +35,11 @@ let { }[] } = $props(); +// If not all peers are online we show the decommission button +let all_reachable = $derived(peers.reduce((acc, val) => { + return val.reachable ? acc : false +}, true)) + $effect(() => { for (let peer of peers) { peer.avg_network_total = peer.avg_network_tx + peer.avg_network_rx @@ -74,6 +81,16 @@ let sort = (field: string) => { }) peers = peers } + +const decommission = (id: string) => { + loading_run(async () => { + try { + await admin_decommission_node(id) + } catch (err) { + alert(JSON.stringify(err)) + } + }) +}
@@ -92,16 +109,17 @@ let sort = (field: string) => { CThresh Free Min free + {#if !all_reachable}{/if} - {#each peers as peer (peer.ip)} + {#each peers as peer (peer.id)} {peer.hostname} {peer.unreachable_count} @@ -115,6 +133,13 @@ let sort = (field: string) => { {formatDataVolume(peer.cache_threshold, 3)} {formatDataVolume(peer.free_space, 3)} {formatDataVolume(peer.min_free_space, 3)} + {#if !all_reachable} + + + + {/if} {/each} @@ -135,6 +160,7 @@ let sort = (field: string) => { {formatDataVolume(peers.reduce((acc, val) => acc += val.cache_threshold, 0), 4)} {formatDataVolume(peers.reduce((acc, val) => acc += val.free_space, 0), 4)} {formatDataVolume(peers.reduce((acc, val) => acc += val.min_free_space, 0), 3)} + {#if !all_reachable}{/if} Average @@ -153,6 +179,7 @@ let sort = (field: string) => { {formatDataVolume(peers.reduce((acc, val) => acc += val.cache_threshold, 0) / peers.length, 4)} {formatDataVolume(peers.reduce((acc, val) => acc += val.free_space, 0) / peers.length, 4)} {formatDataVolume(peers.reduce((acc, val) => acc += val.min_free_space, 0) / peers.length, 3)} + {#if !all_reachable}{/if} @@ -167,4 +194,7 @@ let sort = (field: string) => { tr { text-align: initial; } +.delete { + margin: 0; +} diff --git a/svelte/src/lib/AdminAPI.ts b/svelte/src/lib/AdminAPI.ts index bff239d..59b2c3a 100644 --- a/svelte/src/lib/AdminAPI.ts +++ b/svelte/src/lib/AdminAPI.ts @@ -1,5 +1,5 @@ import { countries } from "country-data-list" -import { check_response, get_endpoint } from "./NovaAPI" +import { check_response, get_endpoint, type GenericResponse } from "./NovaAPI" export const country_name = (country: string) => { if (country !== "" && countries[country] !== undefined) { @@ -27,3 +27,15 @@ export const get_admin_invoices = async (year: number, month: number) => { ) ) as Invoice[] }; + +export const admin_decommission_node = async (peer_id: string) => { + let form = new FormData() + form.set("peer_id", peer_id) + + return await check_response( + await fetch( + get_endpoint() + "/admin/decommission_node", + { method: "POST", body: form } + ) + ) as GenericResponse +};