This commit is contained in:
parent
c908d00c62
commit
20e6d7931e
@ -40,6 +40,7 @@ struct ServerConstraints {
|
||||
vnc_token_duration: u64,
|
||||
vm_name_size: LenConstraints,
|
||||
vm_title_size: LenConstraints,
|
||||
group_id_size: LenConstraints,
|
||||
memory_size: LenConstraints,
|
||||
disk_name_size: LenConstraints,
|
||||
disk_size: LenConstraints,
|
||||
@ -72,6 +73,7 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder {
|
||||
|
||||
vm_name_size: LenConstraints { min: 2, max: 50 },
|
||||
vm_title_size: LenConstraints { min: 0, max: 50 },
|
||||
group_id_size: LenConstraints { min: 3, max: 50 },
|
||||
memory_size: LenConstraints {
|
||||
min: constants::MIN_VM_MEMORY,
|
||||
max: constants::MAX_VM_MEMORY,
|
||||
|
@ -211,7 +211,7 @@ async fn main() -> std::io::Result<()> {
|
||||
)
|
||||
.route("/api/vnc", web::get().to(vm_controller::vnc))
|
||||
// Groups controller
|
||||
.route("/api/groups/list", web::get().to(groups_controller::list))
|
||||
.route("/api/group/list", web::get().to(groups_controller::list))
|
||||
// Network controller
|
||||
.route(
|
||||
"/api/network/create",
|
||||
|
15
virtweb_frontend/src/api/GroupApi.ts
Normal file
15
virtweb_frontend/src/api/GroupApi.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { APIClient } from "./ApiClient";
|
||||
|
||||
export class GroupApi {
|
||||
/**
|
||||
* Get the entire list of networks
|
||||
*/
|
||||
static async GetList(): Promise<string[]> {
|
||||
return (
|
||||
await APIClient.exec({
|
||||
method: "GET",
|
||||
uri: "/group/list",
|
||||
})
|
||||
).data;
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ export interface ServerConstraints {
|
||||
vnc_token_duration: number;
|
||||
vm_name_size: LenConstraint;
|
||||
vm_title_size: LenConstraint;
|
||||
group_id_size: LenConstraint;
|
||||
memory_size: LenConstraint;
|
||||
disk_name_size: LenConstraint;
|
||||
disk_size: LenConstraint;
|
||||
|
@ -63,6 +63,7 @@ interface VMInfoInterface {
|
||||
genid?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
group?: string;
|
||||
boot_type: "UEFI" | "UEFISecureBoot";
|
||||
architecture: "i686" | "x86_64";
|
||||
memory: number;
|
||||
@ -80,6 +81,7 @@ export class VMInfo implements VMInfoInterface {
|
||||
genid?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
group?: string;
|
||||
boot_type: "UEFI" | "UEFISecureBoot";
|
||||
architecture: "i686" | "x86_64";
|
||||
number_vcpu: number;
|
||||
@ -96,6 +98,7 @@ export class VMInfo implements VMInfoInterface {
|
||||
this.genid = int.genid;
|
||||
this.title = int.title;
|
||||
this.description = int.description;
|
||||
this.group = int.group;
|
||||
this.boot_type = int.boot_type;
|
||||
this.architecture = int.architecture;
|
||||
this.number_vcpu = int.number_vcpu;
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { Button } from "@mui/material";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import ListIcon from "@mui/icons-material/List";
|
||||
import { Button, IconButton, Tooltip } from "@mui/material";
|
||||
import Grid from "@mui/material/Grid2";
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { validate as validateUUID } from "uuid";
|
||||
import { GroupApi } from "../../api/GroupApi";
|
||||
import { IsoFile, IsoFilesApi } from "../../api/IsoFilesApi";
|
||||
import { NWFilter, NWFilterApi } from "../../api/NWFilterApi";
|
||||
import { NetworkApi, NetworkInfo } from "../../api/NetworksApi";
|
||||
@ -32,6 +35,7 @@ interface DetailsProps {
|
||||
}
|
||||
|
||||
export function VMDetails(p: DetailsProps): React.ReactElement {
|
||||
const [groupsList, setGroupsList] = React.useState<string[] | any>();
|
||||
const [isoList, setIsoList] = React.useState<IsoFile[] | any>();
|
||||
const [vcpuCombinations, setVCPUCombinations] = React.useState<
|
||||
number[] | any
|
||||
@ -42,6 +46,7 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
|
||||
>();
|
||||
|
||||
const load = async () => {
|
||||
setGroupsList(await GroupApi.GetList());
|
||||
setIsoList(await IsoFilesApi.GetList());
|
||||
setVCPUCombinations(await ServerApi.NumberVCPUs());
|
||||
setNetworksList(await NetworkApi.GetList());
|
||||
@ -55,6 +60,7 @@ export function VMDetails(p: DetailsProps): React.ReactElement {
|
||||
errMsg="Failed to load the list of ISO files"
|
||||
build={() => (
|
||||
<VMDetailsInner
|
||||
groupsList={groupsList}
|
||||
isoList={isoList}
|
||||
vcpuCombinations={vcpuCombinations}
|
||||
networksList={networksList}
|
||||
@ -75,6 +81,7 @@ enum VMTab {
|
||||
}
|
||||
|
||||
type DetailsInnerProps = DetailsProps & {
|
||||
groupsList: string[];
|
||||
isoList: IsoFile[];
|
||||
vcpuCombinations: number[];
|
||||
networksList: NetworkInfo[];
|
||||
@ -117,6 +124,8 @@ function VMDetailsInner(p: DetailsInnerProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function VMDetailsTabGeneral(p: DetailsInnerProps): React.ReactElement {
|
||||
const [addGroup, setAddGroup] = React.useState(false);
|
||||
|
||||
return (
|
||||
<Grid container spacing={2}>
|
||||
{
|
||||
@ -175,6 +184,50 @@ function VMDetailsTabGeneral(p: DetailsInnerProps): React.ReactElement {
|
||||
}}
|
||||
multiline={true}
|
||||
/>
|
||||
|
||||
<div style={{ display: "flex" }}>
|
||||
{addGroup ? (
|
||||
<TextInput
|
||||
label="Group"
|
||||
editable={p.editable}
|
||||
value={p.vm.group}
|
||||
onValueChange={(v) => {
|
||||
p.vm.group = v;
|
||||
p.onChange?.();
|
||||
}}
|
||||
size={ServerApi.Config.constraints.group_id_size}
|
||||
/>
|
||||
) : (
|
||||
<SelectInput
|
||||
editable={p.editable}
|
||||
label="Group"
|
||||
onValueChange={(v) => {
|
||||
p.vm.group = v! as any;
|
||||
p.onChange?.();
|
||||
}}
|
||||
value={p.vm.group}
|
||||
options={[
|
||||
{ label: "None" },
|
||||
...p.groupsList.map((g) => {
|
||||
return { value: g, label: g };
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
{p.editable && (
|
||||
<Tooltip
|
||||
title={
|
||||
addGroup
|
||||
? "Use an existing group"
|
||||
: "Add a new group instead of using existing one"
|
||||
}
|
||||
>
|
||||
<IconButton onClick={() => setAddGroup(!addGroup)}>
|
||||
{addGroup ? <ListIcon /> : <AddIcon />}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</EditSection>
|
||||
|
||||
{/* General section */}
|
||||
|
Loading…
Reference in New Issue
Block a user