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
+};