Admin: Basic node listing
This commit is contained in:
parent
c9ac65eaad
commit
0f60436b2c
11 changed files with 223 additions and 58 deletions
frontend
|
@ -1,5 +1,6 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import AdminDashboardView from "@/views/AdminDashboardView.vue";
|
||||
import AdminNodesView from "@/views/AdminNodesView.vue";
|
||||
import HomeView from "@/views/HomeView.vue";
|
||||
|
||||
const router = createRouter({
|
||||
|
@ -15,6 +16,11 @@ const router = createRouter({
|
|||
name: "admin",
|
||||
component: AdminDashboardView,
|
||||
},
|
||||
{
|
||||
path: "/admin/nodes",
|
||||
name: "admin-nodes",
|
||||
component: AdminNodesView,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
29
frontend/src/stores/nodes.ts
Normal file
29
frontend/src/stores/nodes.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import {defineStore} from "pinia";
|
||||
import {isEnhancedNodes, type EnhancedNode} from "@/types";
|
||||
import {internalApi} from "@/utils/Api";
|
||||
|
||||
interface NodesStoreState {
|
||||
nodes: EnhancedNode[];
|
||||
}
|
||||
|
||||
export const useNodesStore = defineStore({
|
||||
id: "nodes",
|
||||
state(): NodesStoreState {
|
||||
return {
|
||||
nodes: [],
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
getNodes(state: NodesStoreState): EnhancedNode[] {
|
||||
return state.nodes;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async refresh(): Promise<void> {
|
||||
this.nodes = await internalApi.get<EnhancedNode[]>(
|
||||
"nodes",
|
||||
isEnhancedNodes
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,3 +1,5 @@
|
|||
import type {TypeGuard} from "@/types/shared";
|
||||
|
||||
class Api {
|
||||
private baseURL: string = import.meta.env.BASE_URL;
|
||||
private apiPrefix = "api/";
|
||||
|
@ -12,7 +14,7 @@ class Api {
|
|||
return this.baseURL + this.apiPrefix + path;
|
||||
}
|
||||
|
||||
async get<T>(path: string, isT: (arg: unknown) => arg is T): Promise<T> {
|
||||
async get<T>(path: string, isT: TypeGuard<T>): Promise<T> {
|
||||
const url = this.toURL(path);
|
||||
const result = await fetch(url);
|
||||
const json = await result.json();
|
||||
|
|
61
frontend/src/views/AdminNodesView.vue
Normal file
61
frontend/src/views/AdminNodesView.vue
Normal file
|
@ -0,0 +1,61 @@
|
|||
<script setup lang="ts">
|
||||
import {useNodesStore} from "@/stores/nodes";
|
||||
import {ref} from "vue";
|
||||
import type {MAC} from "@/types";
|
||||
|
||||
type NodeRedactField = "nickname" | "email" | "token";
|
||||
type NodeRedactFieldsMap = Partial<Record<NodeRedactField, boolean>>;
|
||||
type NodesRedactFieldsMap = Partial<Record<MAC, NodeRedactFieldsMap>>;
|
||||
|
||||
const nodes = useNodesStore();
|
||||
const page = ref(0);
|
||||
|
||||
function refresh(): void {
|
||||
nodes.refresh();
|
||||
}
|
||||
|
||||
refresh();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<h2>Knoten</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Besitzer*in</th>
|
||||
<th>E-Mail</th>
|
||||
<th>Token</th>
|
||||
<th>MAC</th>
|
||||
<th>VPN</th>
|
||||
<th>Site</th>
|
||||
<th>Domäne</th>
|
||||
<th>GPS</th>
|
||||
<th>Status</th>
|
||||
<th>Monitoring</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="node in nodes.getNodes">
|
||||
<td>{{node.hostname}}</td>
|
||||
<td>{{node.nickname}}</td><!-- TODO: Redact values -->
|
||||
<td>{{node.email}}</td><!-- TODO: Redact values -->
|
||||
<td>{{node.token}}</td><!-- TODO: Redact values -->
|
||||
<td>{{node.mac}}</td>
|
||||
<td>{{node.key}}</td><!-- TODO: Icon if set -->
|
||||
<td>{{node.site}}</td>
|
||||
<td>{{node.domain}}</td>
|
||||
<td>{{node.coords}}</td><!-- TODO: Icon with link if set -->
|
||||
<td>{{node.onlineState}}</td>
|
||||
<td>{{node.monitoring}}</td><!-- TODO: Icon regarding state -->
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
|
@ -7,6 +7,8 @@
|
|||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
},
|
||||
"target": "es2018",
|
||||
"lib": ["es2018"],
|
||||
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue