feat: add Deployment Jobs, Template Categories, Virtual Machine details and management pages
- Implemented DeploymentJobsPage for managing deployment jobs with filtering and retry functionality. - Created TemplateCategoriesPage for managing template categories with add, edit, and delete capabilities. - Developed VirtualMachineDetailsPage to display detailed information about a specific virtual machine. - Added VirtualMachinesPage for listing, adding, editing, and deleting virtual machines, including linking and unlinking to domains.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
Button,
|
||||
Combobox,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogBody,
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
Field,
|
||||
Input,
|
||||
makeStyles,
|
||||
Option,
|
||||
shorthands,
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -19,7 +21,7 @@ import {
|
||||
TableRow,
|
||||
Tooltip,
|
||||
} from "@fluentui/react-components";
|
||||
import { AddRegular, DeleteRegular, EditRegular, OpenRegular } from "@fluentui/react-icons";
|
||||
import { AddRegular, DeleteRegular, EditRegular, OpenRegular, LinkMultiple24Regular } from "@fluentui/react-icons";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { portalApi } from "../api/portalApi";
|
||||
@@ -31,6 +33,7 @@ const useStyles = makeStyles({
|
||||
toolbar: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
gap: "10px",
|
||||
marginBottom: "18px",
|
||||
},
|
||||
form: {
|
||||
@@ -54,10 +57,16 @@ export function DomainsPage() {
|
||||
const [name, setName] = useState("");
|
||||
const [fqdn, setFqdn] = useState("");
|
||||
const [netBIOS, setNetBIOS] = useState("");
|
||||
const [linkDomainId, setLinkDomainId] = useState("");
|
||||
const [environmentId, setEnvironmentId] = useState("");
|
||||
const { data, error, isLoading } = useQuery({
|
||||
queryKey: ["domains"],
|
||||
queryFn: ({ signal }) => portalApi.getDomains(signal),
|
||||
});
|
||||
const { data: environments, error: environmentsError, isLoading: environmentsLoading } = useQuery({
|
||||
queryKey: ["environments"],
|
||||
queryFn: ({ signal }) => portalApi.getEnvironments(signal),
|
||||
});
|
||||
|
||||
const closeDialog = () => {
|
||||
setDialogMode(null);
|
||||
@@ -83,6 +92,11 @@ export function DomainsPage() {
|
||||
setDialogMode("edit");
|
||||
};
|
||||
|
||||
const openLinkDialog = () => {
|
||||
setLinkDomainId(data?.[0]?.id ?? "");
|
||||
setEnvironmentId(environments?.[0]?.id ?? "");
|
||||
};
|
||||
|
||||
const addDomain = useMutation({
|
||||
mutationFn: portalApi.addDomain,
|
||||
onSuccess: async () => {
|
||||
@@ -106,6 +120,16 @@ export function DomainsPage() {
|
||||
await queryClient.invalidateQueries({ queryKey: ["domains"] });
|
||||
},
|
||||
});
|
||||
const linkDomainToEnvironment = useMutation({
|
||||
mutationFn: ({ domainId, environmentId: targetEnvironmentId }: { domainId: string; environmentId: string }) =>
|
||||
portalApi.linkDomainToEnvironment(domainId, targetEnvironmentId),
|
||||
onSuccess: async () => {
|
||||
setLinkDomainId("");
|
||||
setEnvironmentId("");
|
||||
await queryClient.invalidateQueries({ queryKey: ["domains"] });
|
||||
await queryClient.invalidateQueries({ queryKey: ["environments"] });
|
||||
},
|
||||
});
|
||||
|
||||
const submitDomain = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
@@ -129,6 +153,9 @@ export function DomainsPage() {
|
||||
<Button appearance="primary" icon={<AddRegular />} onClick={openAddDialog}>
|
||||
Domain hinzufuegen
|
||||
</Button>
|
||||
<Button appearance="secondary" icon={<LinkMultiple24Regular />} onClick={openLinkDialog}>
|
||||
Link to Environment
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Dialog open={dialogMode !== null} onOpenChange={(_, data) => !data.open && closeDialog()}>
|
||||
@@ -159,8 +186,72 @@ export function DomainsPage() {
|
||||
</form>
|
||||
</DialogSurface>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
open={Boolean(linkDomainId || environmentId)}
|
||||
onOpenChange={(_, dialogData) => {
|
||||
if (!dialogData.open) {
|
||||
setLinkDomainId("");
|
||||
setEnvironmentId("");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogSurface>
|
||||
<DialogBody>
|
||||
<DialogTitle>Link to Environment</DialogTitle>
|
||||
<DialogContent className={styles.form}>
|
||||
<Field label="Domain" required>
|
||||
<Combobox
|
||||
placeholder="Domain waehlen"
|
||||
value={data?.find((domain) => domain.id === linkDomainId)?.name ?? ""}
|
||||
onOptionSelect={(_, optionData) => setLinkDomainId(optionData.optionValue ?? "")}
|
||||
>
|
||||
{(data ?? []).map((domain) => (
|
||||
<Option key={domain.id} text={domain.name} value={domain.id}>
|
||||
{domain.name}
|
||||
</Option>
|
||||
))}
|
||||
</Combobox>
|
||||
</Field>
|
||||
<Field label="Environment" required validationMessage={linkDomainToEnvironment.error?.message}>
|
||||
<Combobox
|
||||
disabled={environmentsLoading}
|
||||
placeholder="Environment waehlen"
|
||||
value={environments?.find((environment) => environment.id === environmentId)?.name ?? ""}
|
||||
onOptionSelect={(_, data) => setEnvironmentId(data.optionValue ?? "")}
|
||||
>
|
||||
{(environments ?? []).map((environment) => (
|
||||
<Option key={environment.id} text={environment.name} value={environment.id}>
|
||||
{environment.name}
|
||||
</Option>
|
||||
))}
|
||||
</Combobox>
|
||||
</Field>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
appearance="secondary"
|
||||
onClick={() => {
|
||||
setLinkDomainId("");
|
||||
setEnvironmentId("");
|
||||
}}
|
||||
>
|
||||
Abbrechen
|
||||
</Button>
|
||||
<Button
|
||||
appearance="primary"
|
||||
disabled={!linkDomainId || !environmentId || linkDomainToEnvironment.isPending}
|
||||
onClick={() => {
|
||||
linkDomainToEnvironment.mutate({ domainId: linkDomainId, environmentId });
|
||||
}}
|
||||
>
|
||||
Link
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</DialogBody>
|
||||
</DialogSurface>
|
||||
</Dialog>
|
||||
|
||||
<DataState isLoading={isLoading} error={error ?? deleteDomain.error} />
|
||||
<DataState isLoading={isLoading || environmentsLoading} error={error ?? environmentsError ?? deleteDomain.error ?? linkDomainToEnvironment.error} />
|
||||
{data && (
|
||||
<Table aria-label="Domains">
|
||||
<TableHeader>
|
||||
|
||||
Reference in New Issue
Block a user