server-worklog/frontend/app/pages/servers/index.vue

224 lines
7.3 KiB
Vue

<script setup lang="ts">
import { ref, onMounted } from "vue"
const { apiFetch } = useApi()
const servers = ref([])
const newServer = ref({
hostname: "",
description: "",
owner_id: null
})
const loading = ref(false)
const error = ref("")
const editingId = ref<number | null>(null)
const editServer = ref({
hostname: "",
description: "",
owner_id: null
})
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 saveEdit(serverId: number) {
try {
const updated = await apiFetch(`/servers/${serverId}`, {
method: "PUT",
body: {
hostname: editServer.value.hostname,
description: editServer.value.description,
owner_id: editServer.value.owner_id
}
})
// Liste aktualisieren
const idx = servers.value.findIndex(s => s.id === serverId)
if (idx !== -1) servers.value[idx] = updated
editingId.value = null
} catch (e: any) {
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(() => {
loadOwners()
loadServers()
})
</script>
<template>
<div class="space-y-6">
<h1 class="text-3xl font-bold">Server Verwaltung</h1>
<!-- Neues Server-Formular -->
<div class="p-4 bg-white shadow rounded space-y-4">
<h2 class="text-xl font-semibold">Neuen Server anlegen</h2>
<div class="flex flex-col gap-4">
<input v-model="newServer.hostname" type="text" placeholder="Server Name" class="border p-2 rounded" />
<textarea v-model="newServer.description" placeholder="Beschreibung (optional)"
class="border p-2 rounded" />
<select v-model="newServer.owner_id" class="border p-2 rounded">
<option :value="null">Kein Owner</option>
<option v-for="owner in owners" :key="owner.id" :value="owner.id">
{{ owner.name }}
</option>
</select>
<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>
</template>