Frontend: Owner selection for Server

This commit is contained in:
Frank Agerholm 2026-01-25 17:34:05 +01:00
commit 034d676463
No known key found for this signature in database

View file

@ -5,106 +5,220 @@ const { apiFetch } = useApi()
const servers = ref([]) const servers = ref([])
const newServer = ref({ const newServer = ref({
hostname: "", hostname: "",
description: "" description: "",
owner_id: null
}) })
const loading = ref(false) const loading = ref(false)
const error = ref("") const error = ref("")
async function loadServers() { const editingId = ref<number | null>(null)
loading.value = true
try { const editServer = ref({
servers.value = await apiFetch("/servers") hostname: "",
} catch (e: any) { description: "",
error.value = e.message owner_id: null
} finally { })
loading.value = false
function startEdit(server: any) {
editingId.value = Number(server.id)
editServer.value = {
hostname: server.hostname,
description: server.description,
owner_id: server.owner_id
} }
} }
function cancelEdit() {
editingId.value = null
}
async function createServer() { async function saveEdit(serverId: number) {
if (!newServer.value.hostname.trim()) return
try { try {
const server = await apiFetch("/servers", { const updated = await apiFetch(`/servers/${serverId}`, {
method: "POST", method: "PUT",
body: { body: {
hostname: newServer.value.hostname, hostname: editServer.value.hostname,
description: newServer.value.description description: editServer.value.description,
owner_id: editServer.value.owner_id
} }
}) })
servers.value.push(server) // Liste aktualisieren
newServer.value = { hostname: "", description: "" } const idx = servers.value.findIndex(s => s.id === serverId)
if (idx !== -1) servers.value[idx] = updated
editingId.value = null
} catch (e: any) { } catch (e: any) {
error.value = e.message error.value = e.message
} }
} }
const owners = ref([])
async function loadOwners() {
try {
owners.value = await apiFetch("/owners")
} catch (e: any) {
error.value = e.message
}
}
async function loadServers() {
loading.value = true
try {
servers.value = await apiFetch("/servers")
} catch (e: any) {
error.value = e.message
} finally {
loading.value = false
}
}
async function createServer() {
if (!newServer.value.hostname.trim()) return
try {
const server = await apiFetch("/servers", {
method: "POST",
body: {
hostname: newServer.value.hostname,
description: newServer.value.description,
owner_id: newServer.value.owner_id
}
})
servers.value.push(server)
newServer.value = { hostname: "", description: "" }
} catch (e: any) {
error.value = e.message
}
}
onMounted(() => { onMounted(() => {
loadServers() loadOwners()
loadServers()
}) })
</script> </script>
<template> <template>
<div class="space-y-6"> <div class="space-y-6">
<h1 class="text-3xl font-bold">Server Verwaltung</h1> <h1 class="text-3xl font-bold">Server Verwaltung</h1>
<!-- Neues Server-Formular --> <!-- Neues Server-Formular -->
<div class="p-4 bg-white shadow rounded space-y-4"> <div class="p-4 bg-white shadow rounded space-y-4">
<h2 class="text-xl font-semibold">Neuen Server anlegen</h2> <h2 class="text-xl font-semibold">Neuen Server anlegen</h2>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<input <input v-model="newServer.hostname" type="text" placeholder="Server Name" class="border p-2 rounded" />
v-model="newServer.hostname"
type="text"
placeholder="Server Name"
class="border p-2 rounded"
/>
<textarea <textarea v-model="newServer.description" placeholder="Beschreibung (optional)"
v-model="newServer.description" class="border p-2 rounded" />
placeholder="Beschreibung (optional)"
class="border p-2 rounded"
/>
<button <select v-model="newServer.owner_id" class="border p-2 rounded">
@click="createServer" <option :value="null">Kein Owner</option>
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 self-start" <option v-for="owner in owners" :key="owner.id" :value="owner.id">
> {{ owner.name }}
Speichern </option>
</button> </select>
</div>
<button @click="createServer"
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 self-start">
Speichern
</button>
</div>
</div>
<!-- Server-Liste -->
<div class="p-4 bg-white shadow rounded">
<h2 class="text-xl font-semibold mb-4">Server Liste</h2>
<div v-if="loading">Lade Server</div>
<div v-if="error" class="text-red-600">{{ error }}</div>
<table class="w-full border-collapse">
<thead>
<tr class="border-b">
<th class="text-left p-2">ID</th>
<th class="text-left p-2">Name</th>
<th class="text-left p-2">Beschreibung</th>
<th class="text-left p-2">Eigentümer</th>
</tr>
</thead>
<tbody>
<tr v-for="server in servers" :key="server.id" class="border-b hover:bg-gray-50">
<td class="p-2">{{ server.id }}</td>
<td class="p-2">
<template v-if="editingId === server.id">
<input
v-model="editServer.hostname"
class="border p-1 rounded w-full"
/>
</template>
<template v-else>
{{ server.hostname }}
</template>
</td>
<td class="p-2">
<template v-if="editingId === server.id">
<textarea
v-model="editServer.description"
class="border p-1 rounded w-full"
/>
</template>
<template v-else>
{{ server.description }}
</template>
</td>
<td class="p-2">
<template v-if="editingId === server.id">
<select v-model="editServer.owner_id" class="border p-1 rounded">
<option :value="null">Kein Owner</option>
<option
v-for="owner in owners"
:key="owner.id"
:value="owner.id"
>
{{ owner.name }}
</option>
</select>
</template>
<template v-else>
{{ server.owner ? server.owner.name : "—" }}
</template>
</td>
<td class="p-2">
<template v-if="editingId === server.id">
<button
@click="saveEdit(server.id)"
class="bg-green-600 text-white px-2 py-1 rounded mr-2"
>
Speichern
</button>
<button
@click="cancelEdit"
class="bg-gray-400 text-white px-2 py-1 rounded"
>
Abbrechen
</button>
</template>
<template v-else>
<button
@click="startEdit(server)"
class="bg-blue-600 text-white px-2 py-1 rounded"
>
Bearbeiten
</button>
</template>
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
<!-- Server-Liste -->
<div class="p-4 bg-white shadow rounded">
<h2 class="text-xl font-semibold mb-4">Server Liste</h2>
<div v-if="loading">Lade Server</div>
<div v-if="error" class="text-red-600">{{ error }}</div>
<table class="w-full border-collapse">
<thead>
<tr class="border-b">
<th class="text-left p-2">ID</th>
<th class="text-left p-2">Name</th>
<th class="text-left p-2">Beschreibung</th>
</tr>
</thead>
<tbody>
<tr
v-for="server in servers"
:key="server.id"
class="border-b hover:bg-gray-50"
>
<td class="p-2">{{ server.id }}</td>
<td class="p-2">{{ server.hostname }}</td>
<td class="p-2">{{ server.description }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template> </template>