Restructure UX and seed a fully simulated organisation
Some checks failed
CI / Tests (push) Failing after 56s
CI / Lint (push) Failing after 1m35s

Rework the dashboard, environment topology view, header navigation, and
status rendering, and standardise selects on a shadcn-vue component.

Replace the thin database seeder with a SimulatedEnvironmentSeeder that
builds a fully wired, mostly-running organisation (ACTIVE server fleet,
managed + GHCR registries, Gitea source provider, ClipBin app with
production/staging environments, services, slices, endpoints, managed
variables, build artifacts, and a completed/in-progress/failed operations
history) so the new UI renders against realistic data.
This commit is contained in:
2026-06-08 22:09:57 +01:00
parent 3a851db08f
commit 85c44296ac
58 changed files with 2292 additions and 847 deletions

View File

@@ -6,6 +6,13 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import AppLayout from "@/layouts/AppLayout.vue";
import { Head, Link, router, useForm } from "@inertiajs/vue3";
import { useCycleList, useInterval } from "@vueuse/core";
@@ -204,7 +211,10 @@ const healServer = (): void => {
<h3 class="mb-3 text-2xl font-semibold tracking-tight">Operations</h3>
<Card>
<CardContent class="py-4">
<OperationTimeline :operations="server.service_operations" show-target />
<OperationTimeline
:operations="server.service_operations"
show-target
/>
</CardContent>
</Card>
</div>
@@ -212,22 +222,29 @@ const healServer = (): void => {
<Card>
<CardHeader>
<CardTitle>Firewall</CardTitle>
<CardDescription>Rules Keystone knows about for this server.</CardDescription>
<CardDescription
>Rules Keystone knows about for this server.</CardDescription
>
</CardHeader>
<CardContent class="grid gap-4">
<form class="grid gap-3 rounded-md border p-3" @submit.prevent="addFirewallRule">
<div class="grid gap-3 md:grid-cols-[120px_1fr_1fr_auto] md:items-end">
<form
class="grid gap-3 rounded-md border p-3"
@submit.prevent="addFirewallRule"
>
<div
class="grid gap-3 md:grid-cols-[120px_1fr_1fr_auto] md:items-end"
>
<div class="grid gap-2">
<Label for="firewall_type">Action</Label>
<select
id="firewall_type"
v-model="firewallForm.type"
class="h-9 rounded-md border border-input bg-transparent px-3 text-sm"
required
>
<option value="allow">allow</option>
<option value="deny">deny</option>
</select>
<Select v-model="firewallForm.type" required>
<SelectTrigger id="firewall_type">
<SelectValue placeholder="Select an action" />
</SelectTrigger>
<SelectContent>
<SelectItem value="allow">allow</SelectItem>
<SelectItem value="deny">deny</SelectItem>
</SelectContent>
</Select>
<InputError :message="firewallForm.errors.type" />
</div>
<div class="grid gap-2">
@@ -261,7 +278,9 @@ const healServer = (): void => {
class="flex flex-wrap items-center justify-between gap-3 rounded-md border p-3 text-sm"
>
<div>
<div class="font-medium">{{ rule.type }} · {{ rule.ports }}</div>
<div class="font-medium">
{{ rule.type }} · {{ rule.ports }}
</div>
<div class="text-muted-foreground">
{{ rule.from ? `from ${rule.from}` : "any source" }} ·
{{ rule.status }}
@@ -293,10 +312,13 @@ const healServer = (): void => {
<div v-if="server.network">
<div class="font-medium">{{ server.network.name }}</div>
<div class="text-muted-foreground">
{{ server.network.ip_range }} · {{ server.network.network_zone }}
{{ server.network.ip_range }} ·
{{ server.network.network_zone }}
</div>
</div>
<div v-else class="text-muted-foreground">No private network attached.</div>
<div v-else class="text-muted-foreground">
No private network attached.
</div>
</CardContent>
</Card>
</div>
@@ -325,7 +347,11 @@ const healServer = (): void => {
</div>
</div>
<div>
<Button size="xs" disabled title="Services can be added after provisioning completes.">
<Button
size="xs"
disabled
title="Services can be added after provisioning completes."
>
<PlusIcon class="size-4" />
Add service
</Button>