VMs are now shown in the search results

This commit is contained in:
headlessdev 2025-04-19 14:39:02 +02:00
parent 44817d6685
commit 86d48bc082
4 changed files with 93 additions and 16 deletions

View File

@ -20,13 +20,25 @@ export async function POST(request: NextRequest) {
});
const hostsWithVms = await Promise.all(
hosts.map(async (host) => ({
...host,
hostedVMs: await prisma.server.findMany({
hosts.map(async (host) => {
const vms = await prisma.server.findMany({
where: { hostServer: host.id },
orderBy: { name: 'asc' }
})
}))
});
// Add isVM flag to VMs
const vmsWithFlag = vms.map(vm => ({
...vm,
isVM: true,
hostedVMs: [] // Initialize empty hostedVMs array for VMs
}));
return {
...host,
isVM: false, // Mark as physical server/not a VM
hostedVMs: vmsWithFlag
};
})
);
const totalHosts = await prisma.server.count({

View File

@ -6,7 +6,15 @@ export async function GET(request: NextRequest) {
const servers = await prisma.server.findMany({
where: { host: true },
});
return NextResponse.json({ servers });
// Add required properties to ensure consistency
const serversWithProps = servers.map(server => ({
...server,
isVM: false,
hostedVMs: [] // Initialize empty hostedVMs array
}));
return NextResponse.json({ servers: serversWithProps });
} catch (error: any) {
return NextResponse.json({ error: error.message }, { status: 500 });
}

View File

@ -11,15 +11,51 @@ export async function POST(request: NextRequest) {
const body: SearchRequest = await request.json();
const { searchterm } = body;
// Fetch all servers
const servers = await prisma.server.findMany({});
// Create a map of host servers with their hosted VMs
const serverMap = new Map();
servers.forEach(server => {
if (server.host) {
serverMap.set(server.id, {
...server,
isVM: false,
hostedVMs: []
});
}
});
// Add VMs to their host servers and mark them as VMs
const serversWithType = servers.map(server => {
// If not a host and has a hostServer, it's a VM
if (!server.host && server.hostServer) {
const hostServer = serverMap.get(server.hostServer);
if (hostServer) {
hostServer.hostedVMs.push({
...server,
isVM: true
});
}
return {
...server,
isVM: true
};
}
return {
...server,
isVM: false,
hostedVMs: serverMap.get(server.id)?.hostedVMs || []
};
});
const fuseOptions = {
keys: ['name', 'description', 'cpu', 'gpu', 'ram', 'disk'],
keys: ['name', 'description', 'cpu', 'gpu', 'ram', 'disk', 'os'],
threshold: 0.3,
includeScore: true,
};
const fuse = new Fuse(servers, fuseOptions);
const fuse = new Fuse(serversWithType, fuseOptions);
const searchResults = fuse.search(searchterm);

View File

@ -94,7 +94,8 @@ interface Server {
gpu?: string;
ram?: string;
disk?: string;
hostedVMs: Server[];
hostedVMs?: Server[];
isVM?: boolean;
}
interface GetServersResponse {
@ -278,6 +279,7 @@ export default function Dashboard() {
{ searchterm: searchTerm }
);
setServers(response.data.results);
setMaxPage(1);
setIsSearching(false);
} catch (error: any) {
console.error("Search error:", error.response?.data);
@ -314,6 +316,13 @@ export default function Dashboard() {
}
}, [isAddDialogOpen, editId]);
// Add this function to get the host server name for a VM
const getHostServerName = (hostServerId: number | null) => {
if (!hostServerId) return "";
const hostServer = servers.find(server => server.id === hostServerId);
return hostServer ? hostServer.name : "";
};
return (
<SidebarProvider>
<AppSidebar />
@ -585,7 +594,7 @@ export default function Dashboard() {
}
>
{servers
.filter((server) => server.hostServer === 0)
.filter((server) => searchTerm ? true : server.hostServer === 0)
.map((server) => (
<Card
key={server.id}
@ -599,8 +608,11 @@ export default function Dashboard() {
<div className="flex items-center justify-between w-full">
<div className="flex items-center">
<div className="ml-4">
<CardTitle className="text-2xl font-bold">
<CardTitle className="text-2xl font-bold flex items-center gap-2">
{server.name}
{server.isVM && (
<span className="bg-blue-500 text-white text-xs px-2 py-1 rounded">VM</span>
)}
</CardTitle>
<CardDescription
className={`text-sm mt-1 grid gap-y-1 ${
@ -621,6 +633,15 @@ export default function Dashboard() {
<b>IP:</b> {server.ip || "Not set"}
</span>
</div>
{server.isVM && server.hostServer && (
<div className="flex items-center gap-2 text-foreground/80">
<Server className="h-4 w-4 text-muted-foreground" />
<span>
<b>Host:</b> {getHostServerName(server.hostServer)}
</span>
</div>
)}
<div className="col-span-full pt-2 pb-2">
<Separator />
@ -841,11 +862,11 @@ export default function Dashboard() {
onCheckedChange={(checked) =>
setEditHost(checked === true)
}
disabled={server.hostedVMs.length > 0}
disabled={server.hostedVMs && server.hostedVMs.length > 0}
/>
<Label htmlFor="editHostCheckbox">
Mark as host server
{server.hostedVMs.length > 0 && (
{server.hostedVMs && server.hostedVMs.length > 0 && (
<span className="text-muted-foreground text-sm ml-2">
(Cannot be disabled while hosting VMs)
</span>
@ -895,7 +916,7 @@ export default function Dashboard() {
</AlertDialogContent>
</AlertDialog>
{server.hostedVMs.length > 0 && (
{server.hostedVMs && server.hostedVMs.length > 0 && (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button
@ -1191,13 +1212,13 @@ export default function Dashboard() {
true
)
}
disabled={server.hostedVMs.length > 0}
disabled={server.hostedVMs && server.hostedVMs.length > 0}
/>
<Label htmlFor="editHostCheckbox">
Mark as
host
server
{server.hostedVMs.length > 0 && (
{server.hostedVMs && server.hostedVMs.length > 0 && (
<span className="text-muted-foreground text-sm ml-2">
(Cannot be disabled while hosting VMs)
</span>